@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.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",
|
|
@@ -4779,12 +4789,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4779
4789
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4780
4790
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4781
4791
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4782
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4783
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4784
4792
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4785
4793
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4786
4794
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4787
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4788
4795
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4789
4796
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4790
4797
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4848,8 +4855,9 @@ class ZipReader {
|
|
|
4848
4855
|
constructor(reader, options = {}) {
|
|
4849
4856
|
Object.assign(this, {
|
|
4850
4857
|
reader: new GenericReader(reader),
|
|
4851
|
-
options,
|
|
4852
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4858
|
+
options: options || {},
|
|
4859
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4860
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4853
4861
|
});
|
|
4854
4862
|
}
|
|
4855
4863
|
|
|
@@ -4920,16 +4928,22 @@ class ZipReader {
|
|
|
4920
4928
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4921
4929
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4922
4930
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4931
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4932
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4933
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4934
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4935
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4936
|
+
}
|
|
4937
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4938
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4939
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4940
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4941
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4942
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4943
|
+
}
|
|
4944
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4945
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4930
4946
|
}
|
|
4931
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4932
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4933
4947
|
}
|
|
4934
4948
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4935
4949
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4974,10 +4988,6 @@ class ZipReader {
|
|
|
4974
4988
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4975
4989
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4976
4990
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4977
|
-
if (directoryDataOffset >= reader.size) {
|
|
4978
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4979
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4980
|
-
}
|
|
4981
4991
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4982
4992
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4983
4993
|
}
|
|
@@ -4985,52 +4995,64 @@ class ZipReader {
|
|
|
4985
4995
|
throw new Error(ERR_BAD_FORMAT);
|
|
4986
4996
|
}
|
|
4987
4997
|
let offset = 0;
|
|
4988
|
-
let directoryArray =
|
|
4998
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4999
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
5000
|
+
EMPTY_UINT8_ARRAY;
|
|
4989
5001
|
let directoryView = getDataView(directoryArray);
|
|
4990
5002
|
if (directoryDataLength) {
|
|
4991
|
-
if (directoryArray.length < 4) {
|
|
4992
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4993
|
-
}
|
|
4994
5003
|
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4995
5004
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4996
|
-
const storedPointsAtDirectory =
|
|
5005
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
5006
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4997
5007
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4998
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
5008
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
5009
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
5010
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5011
|
+
}
|
|
4999
5012
|
let reconcile = !storedPointsAtDirectory;
|
|
5000
5013
|
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
5001
|
-
|
|
5002
|
-
if (
|
|
5003
|
-
reconcile = expectedPointsAtDirectory;
|
|
5004
|
-
} else if (!expectedPointsAtDirectory) {
|
|
5014
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
5015
|
+
if (!expectedPointsAtDirectory) {
|
|
5005
5016
|
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
5006
5017
|
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
5007
5018
|
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
5008
5019
|
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
5009
5020
|
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
5021
|
+
expectedPointsAtDirectory = true;
|
|
5010
5022
|
}
|
|
5011
5023
|
}
|
|
5024
|
+
if (storedPointsAtDirectory) {
|
|
5025
|
+
reconcile = expectedPointsAtDirectory;
|
|
5026
|
+
}
|
|
5012
5027
|
}
|
|
5013
|
-
if (reconcile) {
|
|
5028
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
5014
5029
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
5015
5030
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
5016
5031
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
5017
5032
|
directoryView = getDataView(directoryArray);
|
|
5018
|
-
|
|
5019
|
-
|
|
5033
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5034
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5035
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5036
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5037
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5038
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5039
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5040
|
+
prependedDataLength += offsetDelta;
|
|
5020
5041
|
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5021
5042
|
} else {
|
|
5022
5043
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5026
|
-
if (!await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE) &&
|
|
5027
|
-
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE)) {
|
|
5028
|
-
prependedDataLength += offsetDelta;
|
|
5029
|
-
}
|
|
5044
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5045
|
+
prependedDataLength += offsetDelta;
|
|
5030
5046
|
}
|
|
5031
5047
|
}
|
|
5032
5048
|
}
|
|
5033
5049
|
}
|
|
5050
|
+
if (directoryArray.length < 4) {
|
|
5051
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5052
|
+
}
|
|
5053
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5054
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5055
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
5034
5056
|
}
|
|
5035
5057
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
5036
5058
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -5072,8 +5094,10 @@ class ZipReader {
|
|
|
5072
5094
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5073
5095
|
}
|
|
5074
5096
|
}
|
|
5097
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5098
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
5075
5099
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
5076
|
-
const fileEntry = new ZipEntry$1(reader,
|
|
5100
|
+
const fileEntry = new ZipEntry$1(reader, entryOptions);
|
|
5077
5101
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5078
5102
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
5079
5103
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -5164,13 +5188,17 @@ class ZipReader {
|
|
|
5164
5188
|
if (malformedExtraField) {
|
|
5165
5189
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5166
5190
|
}
|
|
5167
|
-
fileEntry.offset
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5191
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5192
|
+
startOffset = 0;
|
|
5193
|
+
} else {
|
|
5194
|
+
fileEntry.offset += prependedDataLength;
|
|
5195
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5196
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5197
|
+
if (entryPosition < previousEntryPosition) {
|
|
5198
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5199
|
+
}
|
|
5200
|
+
previousEntryPosition = entryPosition;
|
|
5172
5201
|
}
|
|
5173
|
-
previousEntryPosition = entryPosition;
|
|
5174
5202
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5175
5203
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5176
5204
|
}
|
|
@@ -5207,12 +5235,15 @@ class ZipReader {
|
|
|
5207
5235
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5208
5236
|
});
|
|
5209
5237
|
const entry = new Entry(fileEntry);
|
|
5210
|
-
|
|
5238
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5239
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5240
|
+
}
|
|
5241
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5211
5242
|
entry.arrayBuffer = async options => {
|
|
5212
5243
|
const writer = new TransformStream();
|
|
5213
5244
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5214
5245
|
arrayBufferPromise.catch(() => { });
|
|
5215
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5246
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5216
5247
|
Object.assign({}, options, { preventClose: false }));
|
|
5217
5248
|
return arrayBufferPromise;
|
|
5218
5249
|
};
|
|
@@ -5420,8 +5451,9 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5420
5451
|
});
|
|
5421
5452
|
}
|
|
5422
5453
|
|
|
5423
|
-
async getData(writer, fileEntry,
|
|
5454
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5424
5455
|
const zipEntry = this;
|
|
5456
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5425
5457
|
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5426
5458
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5427
5459
|
}
|
|
@@ -5495,10 +5527,10 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5495
5527
|
}
|
|
5496
5528
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5497
5529
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5498
|
-
if (lastAccessDate) {
|
|
5530
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5499
5531
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5500
5532
|
}
|
|
5501
|
-
if (creationDate) {
|
|
5533
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5502
5534
|
fileEntry.creationDate = creationDate;
|
|
5503
5535
|
}
|
|
5504
5536
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5527,7 +5559,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5527
5559
|
throw new Error(ERR_ENCRYPTED);
|
|
5528
5560
|
}
|
|
5529
5561
|
}
|
|
5530
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5562
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5531
5563
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5532
5564
|
}
|
|
5533
5565
|
const size = compressedSize;
|
|
@@ -5593,6 +5625,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5593
5625
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5594
5626
|
readRanges
|
|
5595
5627
|
});
|
|
5628
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5596
5629
|
}
|
|
5597
5630
|
let writable, abortError, aborted;
|
|
5598
5631
|
try {
|
|
@@ -5612,10 +5645,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5612
5645
|
writer.size += writtenSize;
|
|
5613
5646
|
}
|
|
5614
5647
|
} catch (error) {
|
|
5615
|
-
|
|
5616
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5617
|
-
writer.size += failedOutputSize;
|
|
5618
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5648
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5619
5649
|
writer.size += error.outputSize;
|
|
5620
5650
|
}
|
|
5621
5651
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5643,13 +5673,7 @@ let ZipEntry$1 = class ZipEntry {
|
|
|
5643
5673
|
};
|
|
5644
5674
|
|
|
5645
5675
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5646
|
-
|
|
5647
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5648
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5649
|
-
return true;
|
|
5650
|
-
}
|
|
5651
|
-
}
|
|
5652
|
-
return false;
|
|
5676
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5653
5677
|
}
|
|
5654
5678
|
|
|
5655
5679
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5686,6 +5710,46 @@ async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
|
5686
5710
|
}
|
|
5687
5711
|
}
|
|
5688
5712
|
|
|
5713
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5714
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5715
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5716
|
+
const tailView = getDataView(tailArray);
|
|
5717
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5718
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5719
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5720
|
+
return startOffset + indexByte;
|
|
5721
|
+
}
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
5724
|
+
|
|
5725
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5726
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5727
|
+
return UNDEFINED_VALUE;
|
|
5728
|
+
}
|
|
5729
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5730
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5731
|
+
return localHeaderOffset;
|
|
5732
|
+
}
|
|
5733
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5734
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5735
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5736
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5737
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5738
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5739
|
+
let offsetValue = offsetExtraField + 4;
|
|
5740
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5741
|
+
offsetValue += 8;
|
|
5742
|
+
}
|
|
5743
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5744
|
+
offsetValue += 8;
|
|
5745
|
+
}
|
|
5746
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5747
|
+
}
|
|
5748
|
+
offsetExtraField += 4 + size;
|
|
5749
|
+
}
|
|
5750
|
+
return UNDEFINED_VALUE;
|
|
5751
|
+
}
|
|
5752
|
+
|
|
5689
5753
|
function readDigitalSignature(signatureRecordArray) {
|
|
5690
5754
|
if (signatureRecordArray.length >= 6) {
|
|
5691
5755
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5775,6 +5839,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5775
5839
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5776
5840
|
});
|
|
5777
5841
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5842
|
+
let extraFieldZip64Missing;
|
|
5778
5843
|
if (extraFieldZip64) {
|
|
5779
5844
|
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5780
5845
|
malformedExtraField = true;
|
|
@@ -5784,7 +5849,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5784
5849
|
if (localDirectory) {
|
|
5785
5850
|
malformedExtraField = true;
|
|
5786
5851
|
} else {
|
|
5787
|
-
|
|
5852
|
+
extraFieldZip64Missing = true;
|
|
5788
5853
|
}
|
|
5789
5854
|
}
|
|
5790
5855
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
@@ -5842,6 +5907,9 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5842
5907
|
if (extraFieldUSDZ) {
|
|
5843
5908
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5844
5909
|
}
|
|
5910
|
+
if (extraFieldZip64Missing) {
|
|
5911
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5912
|
+
}
|
|
5845
5913
|
return malformedExtraField;
|
|
5846
5914
|
}
|
|
5847
5915
|
|
|
@@ -6056,13 +6124,7 @@ async function detectOverlappingEntry({
|
|
|
6056
6124
|
let dataDescriptorLength = 0;
|
|
6057
6125
|
if (dataDescriptor) {
|
|
6058
6126
|
const zip64 = Boolean(extraFieldZip64);
|
|
6059
|
-
const
|
|
6060
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6061
|
-
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6062
|
-
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6063
|
-
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6064
|
-
const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6065
|
-
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6127
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6066
6128
|
if (localDataDescriptor) {
|
|
6067
6129
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6068
6130
|
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
@@ -6132,6 +6194,25 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
6132
6194
|
return mergedRanges;
|
|
6133
6195
|
}
|
|
6134
6196
|
|
|
6197
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6198
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6199
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6200
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6201
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6202
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6203
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6204
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6205
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6206
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6210
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6211
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6212
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
|
|
6135
6216
|
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6136
6217
|
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6137
6218
|
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
@@ -6391,6 +6472,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6391
6472
|
}
|
|
6392
6473
|
}
|
|
6393
6474
|
|
|
6475
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6476
|
+
const { dataDescriptor } = localDirectory;
|
|
6477
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6478
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6479
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6480
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6481
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6482
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6483
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
|
|
6394
6487
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6395
6488
|
if (reject) {
|
|
6396
6489
|
throwAmbiguousArchive(reason);
|
|
@@ -6493,6 +6586,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6493
6586
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6494
6587
|
ZipReader: ZipReader,
|
|
6495
6588
|
ZipReaderStream: ZipReaderStream,
|
|
6589
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6496
6590
|
isZipFile: isZipFile
|
|
6497
6591
|
});
|
|
6498
6592
|
|
|
@@ -6616,136 +6710,7 @@ class ZipWriter {
|
|
|
6616
6710
|
}
|
|
6617
6711
|
|
|
6618
6712
|
appendZip(reader, options = {}) {
|
|
6619
|
-
return watchPromiseError(this,
|
|
6620
|
-
}
|
|
6621
|
-
|
|
6622
|
-
async appendZipEntries(reader, options = {}) {
|
|
6623
|
-
const zipWriter = this;
|
|
6624
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6625
|
-
const filter = checkFunctionOption(options.filter);
|
|
6626
|
-
while (pendingAddFileCalls.size) {
|
|
6627
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6628
|
-
}
|
|
6629
|
-
let resolveAppendZip;
|
|
6630
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6631
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6632
|
-
const appendedFilenames = [];
|
|
6633
|
-
let releaseLockWriter;
|
|
6634
|
-
try {
|
|
6635
|
-
reader = new GenericReader(reader);
|
|
6636
|
-
await initStream(reader);
|
|
6637
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6638
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6639
|
-
await initStream(reader);
|
|
6640
|
-
}
|
|
6641
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6642
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6643
|
-
const entries = await zipReader$1.getEntries();
|
|
6644
|
-
const keptEntries = [];
|
|
6645
|
-
for (const entry of entries) {
|
|
6646
|
-
if (!filter || await filter(entry)) {
|
|
6647
|
-
keptEntries.push(entry);
|
|
6648
|
-
}
|
|
6649
|
-
}
|
|
6650
|
-
await zipReader$1.close();
|
|
6651
|
-
await initStream(zipWriter.writer);
|
|
6652
|
-
const { directoryOffset } = zipReader$1;
|
|
6653
|
-
keptEntries.forEach(({ filename }) => {
|
|
6654
|
-
if (filenames.has(filename)) {
|
|
6655
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6656
|
-
}
|
|
6657
|
-
filenames.add(filename);
|
|
6658
|
-
appendedFilenames.push(filename);
|
|
6659
|
-
});
|
|
6660
|
-
zipWriter.writerLocked = true;
|
|
6661
|
-
const { lockWriter } = zipWriter;
|
|
6662
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6663
|
-
zipWriter.writerLocked = false;
|
|
6664
|
-
resolve();
|
|
6665
|
-
});
|
|
6666
|
-
await lockWriter;
|
|
6667
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6668
|
-
delete zipWriter.addSplitZipSignature;
|
|
6669
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6670
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6671
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6672
|
-
}
|
|
6673
|
-
}
|
|
6674
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter));
|
|
6675
|
-
keptEntries.forEach(entry => {
|
|
6676
|
-
const {
|
|
6677
|
-
version,
|
|
6678
|
-
rawLastModDate,
|
|
6679
|
-
rawFilename,
|
|
6680
|
-
bitFlag,
|
|
6681
|
-
encrypted,
|
|
6682
|
-
uncompressedSize,
|
|
6683
|
-
compressedSize,
|
|
6684
|
-
extraFieldZip64
|
|
6685
|
-
} = entry;
|
|
6686
|
-
let {
|
|
6687
|
-
compressionMethod,
|
|
6688
|
-
rawExtraField,
|
|
6689
|
-
} = entry;
|
|
6690
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6691
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6692
|
-
if (entry.extraFieldAES) {
|
|
6693
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6694
|
-
}
|
|
6695
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6696
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6697
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6698
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6699
|
-
const {
|
|
6700
|
-
headerArray,
|
|
6701
|
-
headerView
|
|
6702
|
-
} = getHeaderArrayData({
|
|
6703
|
-
version,
|
|
6704
|
-
bitFlag: bitFlagValue,
|
|
6705
|
-
compressionMethod,
|
|
6706
|
-
uncompressedSize,
|
|
6707
|
-
compressedSize,
|
|
6708
|
-
rawLastModDate,
|
|
6709
|
-
rawFilename,
|
|
6710
|
-
zip64CompressedSize,
|
|
6711
|
-
zip64UncompressedSize,
|
|
6712
|
-
extraFieldLength
|
|
6713
|
-
});
|
|
6714
|
-
const { crc32 } = entry;
|
|
6715
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6716
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6717
|
-
}
|
|
6718
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6719
|
-
Object.assign(entry, {
|
|
6720
|
-
zip64Enabled: true,
|
|
6721
|
-
zip64UncompressedSize,
|
|
6722
|
-
zip64CompressedSize,
|
|
6723
|
-
offset,
|
|
6724
|
-
diskNumberStart,
|
|
6725
|
-
zip64DiskNumberStart: false,
|
|
6726
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6728
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6729
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6730
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6731
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6732
|
-
rawExtraField,
|
|
6733
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6734
|
-
headerArray,
|
|
6735
|
-
headerView
|
|
6736
|
-
});
|
|
6737
|
-
fileEntries.set(entry.filename, entry);
|
|
6738
|
-
});
|
|
6739
|
-
} catch (error) {
|
|
6740
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6741
|
-
throw error;
|
|
6742
|
-
} finally {
|
|
6743
|
-
resolveAppendZip();
|
|
6744
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6745
|
-
if (releaseLockWriter) {
|
|
6746
|
-
releaseLockWriter();
|
|
6747
|
-
}
|
|
6748
|
-
}
|
|
6713
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6749
6714
|
}
|
|
6750
6715
|
|
|
6751
6716
|
add(name = "", reader, options = {}) {
|
|
@@ -6907,11 +6872,149 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6907
6872
|
return watchedPromise;
|
|
6908
6873
|
}
|
|
6909
6874
|
|
|
6875
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6876
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6877
|
+
const filter = checkFunctionOption(options.filter);
|
|
6878
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6879
|
+
while (pendingAddFileCalls.size) {
|
|
6880
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6881
|
+
}
|
|
6882
|
+
let resolveAppendZip;
|
|
6883
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6884
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6885
|
+
const appendedFilenames = [];
|
|
6886
|
+
let releaseLockWriter;
|
|
6887
|
+
try {
|
|
6888
|
+
reader = new GenericReader(reader);
|
|
6889
|
+
await initStream(reader);
|
|
6890
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6891
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6892
|
+
await initStream(reader);
|
|
6893
|
+
}
|
|
6894
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6895
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6896
|
+
const keptEntries = [];
|
|
6897
|
+
let entries;
|
|
6898
|
+
try {
|
|
6899
|
+
entries = await zipReader$1.getEntries();
|
|
6900
|
+
for (const entry of entries) {
|
|
6901
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6902
|
+
keptEntries.push(entry);
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
} finally {
|
|
6906
|
+
await zipReader$1.close();
|
|
6907
|
+
}
|
|
6908
|
+
await initStream(zipWriter.writer);
|
|
6909
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6910
|
+
keptEntries.forEach(entry => {
|
|
6911
|
+
const { filename } = entry;
|
|
6912
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6913
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6914
|
+
}
|
|
6915
|
+
if (filenames.has(filename)) {
|
|
6916
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6917
|
+
}
|
|
6918
|
+
filenames.add(filename);
|
|
6919
|
+
appendedFilenames.push(filename);
|
|
6920
|
+
});
|
|
6921
|
+
zipWriter.writerLocked = true;
|
|
6922
|
+
const { lockWriter } = zipWriter;
|
|
6923
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6924
|
+
zipWriter.writerLocked = false;
|
|
6925
|
+
resolve();
|
|
6926
|
+
});
|
|
6927
|
+
await lockWriter;
|
|
6928
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6929
|
+
delete zipWriter.addSplitZipSignature;
|
|
6930
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6931
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6932
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6936
|
+
keptEntries.forEach(entry => {
|
|
6937
|
+
const {
|
|
6938
|
+
version,
|
|
6939
|
+
rawLastModDate,
|
|
6940
|
+
rawFilename,
|
|
6941
|
+
rawBitFlag,
|
|
6942
|
+
uncompressedSize,
|
|
6943
|
+
compressedSize,
|
|
6944
|
+
extraFieldZip64
|
|
6945
|
+
} = entry;
|
|
6946
|
+
let {
|
|
6947
|
+
compressionMethod,
|
|
6948
|
+
rawExtraField,
|
|
6949
|
+
} = entry;
|
|
6950
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6951
|
+
if (entry.extraFieldAES) {
|
|
6952
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6953
|
+
}
|
|
6954
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6955
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6956
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6957
|
+
const {
|
|
6958
|
+
headerArray,
|
|
6959
|
+
headerView
|
|
6960
|
+
} = getHeaderArrayData({
|
|
6961
|
+
version,
|
|
6962
|
+
bitFlag: rawBitFlag,
|
|
6963
|
+
compressionMethod,
|
|
6964
|
+
uncompressedSize,
|
|
6965
|
+
compressedSize,
|
|
6966
|
+
rawLastModDate,
|
|
6967
|
+
rawFilename,
|
|
6968
|
+
zip64CompressedSize,
|
|
6969
|
+
zip64UncompressedSize,
|
|
6970
|
+
extraFieldLength
|
|
6971
|
+
});
|
|
6972
|
+
const { crc32 } = entry;
|
|
6973
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6974
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6975
|
+
}
|
|
6976
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6977
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6978
|
+
zip64Enabled: true,
|
|
6979
|
+
zip64UncompressedSize,
|
|
6980
|
+
zip64CompressedSize,
|
|
6981
|
+
offset,
|
|
6982
|
+
diskNumberStart,
|
|
6983
|
+
zip64DiskNumberStart: false,
|
|
6984
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6985
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6986
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6987
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6988
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6989
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6990
|
+
rawExtraField,
|
|
6991
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6992
|
+
headerArray,
|
|
6993
|
+
headerView
|
|
6994
|
+
}));
|
|
6995
|
+
});
|
|
6996
|
+
} catch (error) {
|
|
6997
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6998
|
+
throw error;
|
|
6999
|
+
} finally {
|
|
7000
|
+
resolveAppendZip();
|
|
7001
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
7002
|
+
if (releaseLockWriter) {
|
|
7003
|
+
releaseLockWriter();
|
|
7004
|
+
}
|
|
7005
|
+
}
|
|
7006
|
+
}
|
|
7007
|
+
|
|
7008
|
+
function getExistingEntry(fileEntries, filename) {
|
|
7009
|
+
const fileEntry = fileEntries.get(filename);
|
|
7010
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
7011
|
+
}
|
|
7012
|
+
|
|
6910
7013
|
async function prependZipEntries(zipWriter, reader) {
|
|
6911
7014
|
if (zipWriter.filenames.size) {
|
|
6912
7015
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6913
7016
|
}
|
|
6914
|
-
await
|
|
7017
|
+
await appendZipEntries(zipWriter, reader);
|
|
6915
7018
|
}
|
|
6916
7019
|
|
|
6917
7020
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -8683,7 +8786,7 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8683
8786
|
return rawExtraField;
|
|
8684
8787
|
}
|
|
8685
8788
|
|
|
8686
|
-
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact) {
|
|
8789
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8687
8790
|
const { writer } = zipWriter;
|
|
8688
8791
|
const entryPositions = new Map();
|
|
8689
8792
|
if (writer.closeDisk || compact) {
|
|
@@ -8691,6 +8794,27 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8691
8794
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8692
8795
|
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8693
8796
|
const keptEntrySet = new Set(keptEntries);
|
|
8797
|
+
const localHeaderLengths = new Map();
|
|
8798
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8799
|
+
const entry = sortedEntries[indexEntry];
|
|
8800
|
+
if (keptEntrySet.has(entry)) {
|
|
8801
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8802
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8803
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8804
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8805
|
+
}
|
|
8806
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8807
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8808
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8809
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8810
|
+
}
|
|
8811
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8812
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8813
|
+
}
|
|
8814
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8815
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8816
|
+
}
|
|
8817
|
+
}
|
|
8694
8818
|
let copiedOffset = 0;
|
|
8695
8819
|
let lastPosition;
|
|
8696
8820
|
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
@@ -8703,7 +8827,7 @@ async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOff
|
|
|
8703
8827
|
if (!compact) {
|
|
8704
8828
|
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8705
8829
|
}
|
|
8706
|
-
if (writer.closeDisk && exceedsAvailableSize(writer,
|
|
8830
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8707
8831
|
await writer.closeDisk();
|
|
8708
8832
|
}
|
|
8709
8833
|
lastPosition = {
|
|
@@ -8737,7 +8861,7 @@ function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
|
8737
8861
|
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8738
8862
|
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8739
8863
|
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8740
|
-
regionEnd = getSourceOffset(reader, nextEntry);
|
|
8864
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8741
8865
|
}
|
|
8742
8866
|
regionEnds[indexEntry] = regionEnd;
|
|
8743
8867
|
}
|
|
@@ -8751,11 +8875,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8751
8875
|
try {
|
|
8752
8876
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8753
8877
|
} catch (error) {
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8878
|
+
if (copiedLength) {
|
|
8879
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8880
|
+
try {
|
|
8881
|
+
error.corruptedEntry = true;
|
|
8882
|
+
} catch {
|
|
8883
|
+
// ignored
|
|
8884
|
+
}
|
|
8759
8885
|
}
|
|
8760
8886
|
throw error;
|
|
8761
8887
|
} finally {
|
|
@@ -8766,11 +8892,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8766
8892
|
}
|
|
8767
8893
|
|
|
8768
8894
|
async function getLocalHeaderLength(reader, offset) {
|
|
8769
|
-
const headerArray =
|
|
8895
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8896
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8897
|
+
EMPTY_UINT8_ARRAY;
|
|
8770
8898
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8771
|
-
return
|
|
8899
|
+
return UNDEFINED_VALUE;
|
|
8772
8900
|
}
|
|
8773
8901
|
const headerView = getDataView(headerArray);
|
|
8902
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8903
|
+
return UNDEFINED_VALUE;
|
|
8904
|
+
}
|
|
8774
8905
|
return HEADER_SIZE +
|
|
8775
8906
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8776
8907
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -9121,7 +9252,7 @@ function formatSupported(StreamClass, format) {
|
|
|
9121
9252
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9122
9253
|
*/
|
|
9123
9254
|
|
|
9124
|
-
const VERSION = "2.
|
|
9255
|
+
const VERSION = "2.22.0";
|
|
9125
9256
|
|
|
9126
9257
|
/*
|
|
9127
9258
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -10196,7 +10327,6 @@ const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
|
10196
10327
|
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
10197
10328
|
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
10198
10329
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
10199
|
-
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
10200
10330
|
const ERR_UNSUPPORTED_PASS_THROUGH_VALUE = "The 'compressed' passThrough option is only supported by Entry#getData() and ZipWriter#add()";
|
|
10201
10331
|
const ERR_INVALID_PASSWORDS = "Invalid passwords option (must be an array of strings)";
|
|
10202
10332
|
const ERR_INVALID_REQUEST_PASSWORD = "Invalid requestPassword option (must be a function returning a string or undefined)";
|
|
@@ -11122,9 +11252,7 @@ function getDeterminedSize(child, passThrough) {
|
|
|
11122
11252
|
}
|
|
11123
11253
|
|
|
11124
11254
|
function checkReaderOptions(readerOptions) {
|
|
11125
|
-
|
|
11126
|
-
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
11127
|
-
}
|
|
11255
|
+
checkReaderOptionsObject(readerOptions);
|
|
11128
11256
|
if (readerOptions) {
|
|
11129
11257
|
checkPassThroughValue(readerOptions.passThrough);
|
|
11130
11258
|
checkPasswordCandidatesOptions(readerOptions);
|