@zip.js/zip.js 2.8.57 → 2.8.59
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 +458 -200
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +472 -199
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +481 -201
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +497 -193
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +481 -201
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +498 -202
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +499 -203
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +474 -201
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +474 -201
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +475 -202
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +498 -202
- package/index-native.min.js +1 -1
- package/index.cjs +499 -203
- package/index.d.cts +297 -10
- package/index.d.ts +297 -10
- package/index.min.js +1 -1
- package/lib/core/constants.js +4 -0
- package/lib/core/options.js +2 -0
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-fs.js +27 -1
- package/lib/core/zip-reader.js +168 -38
- package/lib/core/zip-writer.js +290 -161
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-core-reader.js +16 -1
- package/package.json +1 -1
package/dist/zip-core.js
CHANGED
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
const BITFLAG_LEVEL_FAST_MASK = 0b100;
|
|
84
84
|
const BITFLAG_LEVEL_SUPER_FAST_MASK = 0b110;
|
|
85
85
|
const BITFLAG_DATA_DESCRIPTOR = 0b1000;
|
|
86
|
+
const BITFLAG_COMPRESSED_PATCHED_DATA = 0b100000;
|
|
86
87
|
const BITFLAG_STRONG_ENCRYPTION = 0b1000000;
|
|
87
88
|
const BITFLAG_LANG_ENCODING_FLAG = 0b100000000000;
|
|
88
89
|
const BITFLAG_MASKED_LOCAL_HEADERS = 0b10000000000000;
|
|
@@ -101,6 +102,7 @@
|
|
|
101
102
|
const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
|
|
102
103
|
const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
|
|
103
104
|
|
|
105
|
+
const VERSION_STORE = 0x0A;
|
|
104
106
|
const VERSION_DEFLATE = 0x14;
|
|
105
107
|
const VERSION_ZIP64 = 0x2D;
|
|
106
108
|
const VERSION_AES = 0x33;
|
|
@@ -199,6 +201,7 @@
|
|
|
199
201
|
const OPTION_USDZ = "usdz";
|
|
200
202
|
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
201
203
|
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
204
|
+
const OPTION_CENTRAL_EXTRA_FIELD = "centralExtraField";
|
|
202
205
|
const OPTION_STRICTNESS = "strictness";
|
|
203
206
|
const OPTION_FILENAME_VALIDATION = "filenameValidation";
|
|
204
207
|
const OPTION_NORMALIZE_FILENAME = "normalizeFilename";
|
|
@@ -4708,6 +4711,21 @@
|
|
|
4708
4711
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
4709
4712
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
4710
4713
|
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
4714
|
+
const WARNING_UNSORTED_CENTRAL_DIRECTORY = "unsorted central directory";
|
|
4715
|
+
const WARNING_UNKNOWN_VERSION = "unknown version needed to extract";
|
|
4716
|
+
const WARNING_COMPRESSED_PATCHED_DATA = "compressed patched data";
|
|
4717
|
+
const WARNING_MALFORMED_EXTRA_FIELD = "malformed extra field";
|
|
4718
|
+
const WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = "unknown zip64 extensible data";
|
|
4719
|
+
const WARNING_WRAPPED_ENTRIES_COUNT = "wrapped entries count";
|
|
4720
|
+
const WARNING_APPENDED_DATA = "appended data";
|
|
4721
|
+
const WARNING_PREPENDED_DATA = "prepended data";
|
|
4722
|
+
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4723
|
+
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4724
|
+
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4725
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = "mismatched local file header (general purpose bit flag)";
|
|
4726
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched local file header (compression method)";
|
|
4727
|
+
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4728
|
+
const MAX_KNOWN_VERSION = 63;
|
|
4711
4729
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4712
4730
|
const CHARSET_UTF8 = "utf-8";
|
|
4713
4731
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -4758,6 +4776,7 @@
|
|
|
4758
4776
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
4759
4777
|
throw new Error(ERR_BAD_FORMAT);
|
|
4760
4778
|
}
|
|
4779
|
+
const warnings = zipReader.warnings = [];
|
|
4761
4780
|
const strictness = getStrictness(options, zipReader.options);
|
|
4762
4781
|
const checkAmbiguity = strictness == STRICTNESS_STRICT;
|
|
4763
4782
|
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
@@ -4781,8 +4800,12 @@
|
|
|
4781
4800
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
4782
4801
|
const commentLength = getUint16$1(endOfDirectoryView, 20);
|
|
4783
4802
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
4784
|
-
|
|
4785
|
-
|
|
4803
|
+
const appendedDataLength = reader.size - appendedDataOffset;
|
|
4804
|
+
if (appendedDataLength > maxAppendedDataSize) {
|
|
4805
|
+
throwAmbiguousArchive(WARNING_APPENDED_DATA);
|
|
4806
|
+
}
|
|
4807
|
+
if (appendedDataLength > 0) {
|
|
4808
|
+
addWarning(warnings, WARNING_APPENDED_DATA);
|
|
4786
4809
|
}
|
|
4787
4810
|
let lastDiskNumber = getUint16$1(endOfDirectoryView, 4);
|
|
4788
4811
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
@@ -4836,23 +4859,23 @@
|
|
|
4836
4859
|
}
|
|
4837
4860
|
if (lastDiskNumber == MAX_16_BITS) {
|
|
4838
4861
|
lastDiskNumber = getUint32$1(endOfDirectoryView, 16);
|
|
4839
|
-
} else if (
|
|
4840
|
-
|
|
4862
|
+
} else if (lastDiskNumber != getUint32$1(endOfDirectoryView, 16)) {
|
|
4863
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4841
4864
|
}
|
|
4842
4865
|
if (diskNumber == MAX_16_BITS) {
|
|
4843
4866
|
diskNumber = getUint32$1(endOfDirectoryView, 20);
|
|
4844
|
-
} else if (
|
|
4845
|
-
|
|
4867
|
+
} else if (diskNumber != getUint32$1(endOfDirectoryView, 20)) {
|
|
4868
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4846
4869
|
}
|
|
4847
4870
|
if (filesLength == MAX_16_BITS) {
|
|
4848
4871
|
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
4849
|
-
} else if (
|
|
4850
|
-
|
|
4872
|
+
} else if (filesLength != getBigUint64(endOfDirectoryView, 32)) {
|
|
4873
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4851
4874
|
}
|
|
4852
4875
|
if (directoryDataLength == MAX_32_BITS) {
|
|
4853
4876
|
directoryDataLength = getBigUint64(endOfDirectoryView, 40);
|
|
4854
|
-
} else if (
|
|
4855
|
-
|
|
4877
|
+
} else if (directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
4878
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4856
4879
|
}
|
|
4857
4880
|
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4858
4881
|
}
|
|
@@ -4921,11 +4944,23 @@
|
|
|
4921
4944
|
declaredDirectoryDataLength = directoryArray.length;
|
|
4922
4945
|
decryptedDirectory = true;
|
|
4923
4946
|
}
|
|
4947
|
+
if (directoryEncryptionInfo && !decryptedDirectory &&
|
|
4948
|
+
(directoryArray.length < 4 || getUint32$1(directoryView, 0) == CENTRAL_FILE_HEADER_SIGNATURE)) {
|
|
4949
|
+
addWarning(warnings, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA);
|
|
4950
|
+
}
|
|
4924
4951
|
startOffset = directoryDataOffset;
|
|
4925
4952
|
const filenameEncoding = getOptionValue$1(zipReader, options, OPTION_FILENAME_ENCODING);
|
|
4926
4953
|
const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
|
|
4927
|
-
const filenames =
|
|
4954
|
+
const filenames = new Set();
|
|
4928
4955
|
let duplicateFilename;
|
|
4956
|
+
let previousEntryPosition = -1;
|
|
4957
|
+
const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
|
|
4958
|
+
if (!filesLength && recoverWrappedFilesLength) {
|
|
4959
|
+
filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4960
|
+
if (filesLength) {
|
|
4961
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4929
4964
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4930
4965
|
const fileEntry = new ZipEntry(reader, zipReader.options);
|
|
4931
4966
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -5003,15 +5038,26 @@
|
|
|
5003
5038
|
filename,
|
|
5004
5039
|
comment
|
|
5005
5040
|
});
|
|
5006
|
-
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)
|
|
5041
|
+
if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
|
|
5042
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
5043
|
+
}
|
|
5007
5044
|
fileEntry.offset += prependedDataLength;
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5045
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5046
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5047
|
+
if (entryPosition < previousEntryPosition) {
|
|
5048
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5049
|
+
}
|
|
5050
|
+
previousEntryPosition = entryPosition;
|
|
5051
|
+
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
5052
|
+
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
5053
|
+
}
|
|
5054
|
+
if ((fileEntry.rawBitFlag & BITFLAG_COMPRESSED_PATCHED_DATA) == BITFLAG_COMPRESSED_PATCHED_DATA) {
|
|
5055
|
+
addWarning(warnings, WARNING_COMPRESSED_PATCHED_DATA, filename);
|
|
5014
5056
|
}
|
|
5057
|
+
if (filenames.has(fileEntry.filename)) {
|
|
5058
|
+
duplicateFilename = true;
|
|
5059
|
+
}
|
|
5060
|
+
filenames.add(fileEntry.filename);
|
|
5015
5061
|
const unixExternalUpper = (fileEntry.externalFileAttributes >> 16) & MAX_16_BITS;
|
|
5016
5062
|
if (fileEntry.unixMode === UNDEFINED_VALUE && (unixExternalUpper & (FILE_ATTR_UNIX_DEFAULT_MASK | FILE_ATTR_UNIX_EXECUTABLE_MASK | FILE_ATTR_UNIX_TYPE_DIR)) != 0) {
|
|
5017
5063
|
fileEntry.unixMode = unixExternalUpper;
|
|
@@ -5035,7 +5081,7 @@
|
|
|
5035
5081
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
5036
5082
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
5037
5083
|
executable,
|
|
5038
|
-
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) ||
|
|
5084
|
+
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
|
|
5039
5085
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5040
5086
|
});
|
|
5041
5087
|
const entry = new Entry(fileEntry);
|
|
@@ -5048,6 +5094,13 @@
|
|
|
5048
5094
|
return arrayBufferPromise;
|
|
5049
5095
|
};
|
|
5050
5096
|
offset = endOffset;
|
|
5097
|
+
if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
|
|
5098
|
+
const wrappedFilesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
5099
|
+
if (wrappedFilesLength) {
|
|
5100
|
+
filesLength += wrappedFilesLength;
|
|
5101
|
+
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5051
5104
|
const { onprogress } = options;
|
|
5052
5105
|
if (onprogress) {
|
|
5053
5106
|
try {
|
|
@@ -5072,18 +5125,22 @@
|
|
|
5072
5125
|
zipReader.digitalSignature = digitalSignature;
|
|
5073
5126
|
offsetAfterSignature = offset + 6 + digitalSignature.length;
|
|
5074
5127
|
}
|
|
5075
|
-
if (
|
|
5076
|
-
|
|
5128
|
+
if ((offset != declaredDirectoryDataLength && offsetAfterSignature != declaredDirectoryDataLength) ||
|
|
5129
|
+
(!decryptedDirectory && offset != directoryDataLength && offsetAfterSignature != directoryDataLength)) {
|
|
5130
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA);
|
|
5077
5131
|
}
|
|
5078
5132
|
if (duplicateFilename) {
|
|
5079
|
-
|
|
5133
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_DUPLICATE_FILENAME);
|
|
5080
5134
|
}
|
|
5081
5135
|
const extractPrependedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_PREPENDED_DATA);
|
|
5082
5136
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5083
5137
|
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5084
5138
|
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5085
5139
|
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5086
|
-
throwAmbiguousArchive(
|
|
5140
|
+
throwAmbiguousArchive(WARNING_PREPENDED_DATA);
|
|
5141
|
+
}
|
|
5142
|
+
if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
|
|
5143
|
+
addWarning(warnings, WARNING_PREPENDED_DATA);
|
|
5087
5144
|
}
|
|
5088
5145
|
if (extractPrependedData) {
|
|
5089
5146
|
zipReader.prependedData = startOffset > splitZipSignatureLength ?
|
|
@@ -5153,6 +5210,28 @@
|
|
|
5153
5210
|
}
|
|
5154
5211
|
}
|
|
5155
5212
|
|
|
5213
|
+
async function isZipFile(reader, options = {}) {
|
|
5214
|
+
reader = new GenericReader(reader);
|
|
5215
|
+
await initStream(reader);
|
|
5216
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5217
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5218
|
+
await initStream(reader);
|
|
5219
|
+
}
|
|
5220
|
+
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
5221
|
+
return false;
|
|
5222
|
+
}
|
|
5223
|
+
const strictness = getStrictness(options, {});
|
|
5224
|
+
const rejectAmbiguousEndOfDirectory = strictness != STRICTNESS_TOLERANT;
|
|
5225
|
+
const maxAppendedDataSize = getMaxAppendedDataSize(options[OPTION_MAX_APPENDED_DATA_SIZE], strictness);
|
|
5226
|
+
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
5227
|
+
if (!endOfDirectoryInfo || (strictness == STRICTNESS_STRICT && endOfDirectoryReachingEndCount > 1)) {
|
|
5228
|
+
return false;
|
|
5229
|
+
}
|
|
5230
|
+
const commentLength = getUint16$1(getDataView(endOfDirectoryInfo), 20);
|
|
5231
|
+
const appendedDataOffset = endOfDirectoryInfo.offset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
5232
|
+
return reader.size - appendedDataOffset <= maxAppendedDataSize;
|
|
5233
|
+
}
|
|
5234
|
+
|
|
5156
5235
|
class ZipEntry {
|
|
5157
5236
|
|
|
5158
5237
|
constructor(reader, options) {
|
|
@@ -5184,6 +5263,7 @@
|
|
|
5184
5263
|
dataDescriptor
|
|
5185
5264
|
} = bitFlag;
|
|
5186
5265
|
const localDirectory = fileEntry.localDirectory = {};
|
|
5266
|
+
const warnings = fileEntry.warnings = [];
|
|
5187
5267
|
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
5188
5268
|
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
5189
5269
|
const dataView = getDataView(dataArray);
|
|
@@ -5206,6 +5286,7 @@
|
|
|
5206
5286
|
extraFieldLength,
|
|
5207
5287
|
filenameLength
|
|
5208
5288
|
} = localDirectory;
|
|
5289
|
+
const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5209
5290
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5210
5291
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5211
5292
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
@@ -5223,10 +5304,10 @@
|
|
|
5223
5304
|
if (checkLocalFilename) {
|
|
5224
5305
|
localDirectory.rawFilename = rawLocalFilename;
|
|
5225
5306
|
}
|
|
5226
|
-
readCommonFooter(zipEntry, localDirectory, dataView, 4, true)
|
|
5227
|
-
|
|
5228
|
-
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename);
|
|
5307
|
+
if (readCommonFooter(zipEntry, localDirectory, dataView, 4, true)) {
|
|
5308
|
+
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD);
|
|
5229
5309
|
}
|
|
5310
|
+
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5230
5311
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5231
5312
|
if (lastAccessDate) {
|
|
5232
5313
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
@@ -5259,7 +5340,6 @@
|
|
|
5259
5340
|
throw new Error(ERR_ENCRYPTED);
|
|
5260
5341
|
}
|
|
5261
5342
|
}
|
|
5262
|
-
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5263
5343
|
if (dataOffset + compressedSize > reader.size) {
|
|
5264
5344
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5265
5345
|
}
|
|
@@ -5379,6 +5459,16 @@
|
|
|
5379
5459
|
return false;
|
|
5380
5460
|
}
|
|
5381
5461
|
|
|
5462
|
+
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
5463
|
+
let wrappedFilesLength = 0;
|
|
5464
|
+
while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5465
|
+
offset += CENTRAL_FILE_HEADER_LENGTH +
|
|
5466
|
+
getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
|
|
5467
|
+
wrappedFilesLength++;
|
|
5468
|
+
}
|
|
5469
|
+
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5382
5472
|
function readDigitalSignature(signatureRecordArray) {
|
|
5383
5473
|
if (signatureRecordArray.length >= 6) {
|
|
5384
5474
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5443,6 +5533,7 @@
|
|
|
5443
5533
|
const extraField = directory.extraField = new Map();
|
|
5444
5534
|
const rawExtraFieldView = getDataView(rawExtraField);
|
|
5445
5535
|
let offsetExtraField = 0;
|
|
5536
|
+
let malformedExtraField = false;
|
|
5446
5537
|
try {
|
|
5447
5538
|
while (offsetExtraField < rawExtraField.length) {
|
|
5448
5539
|
const type = getUint16$1(rawExtraFieldView, offsetExtraField);
|
|
@@ -5454,7 +5545,10 @@
|
|
|
5454
5545
|
offsetExtraField += 4 + size;
|
|
5455
5546
|
}
|
|
5456
5547
|
} catch {
|
|
5457
|
-
|
|
5548
|
+
malformedExtraField = true;
|
|
5549
|
+
}
|
|
5550
|
+
if (offsetExtraField > rawExtraField.length) {
|
|
5551
|
+
malformedExtraField = true;
|
|
5458
5552
|
}
|
|
5459
5553
|
const compressionMethod = getUint16$1(dataView, offset + 4);
|
|
5460
5554
|
Object.assign(directory, {
|
|
@@ -5522,6 +5616,7 @@
|
|
|
5522
5616
|
if (extraFieldUSDZ) {
|
|
5523
5617
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5524
5618
|
}
|
|
5619
|
+
return malformedExtraField;
|
|
5525
5620
|
}
|
|
5526
5621
|
|
|
5527
5622
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
@@ -5551,10 +5646,11 @@
|
|
|
5551
5646
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5552
5647
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5553
5648
|
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5649
|
+
const version = getUint8(extraFieldView, 0);
|
|
5554
5650
|
Object.assign(extraFieldUnicode, {
|
|
5555
|
-
version
|
|
5651
|
+
version,
|
|
5556
5652
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5557
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5653
|
+
valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5558
5654
|
});
|
|
5559
5655
|
if (extraFieldUnicode.valid) {
|
|
5560
5656
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5982,27 +6078,46 @@
|
|
|
5982
6078
|
return UNDEFINED_VALUE;
|
|
5983
6079
|
}
|
|
5984
6080
|
|
|
5985
|
-
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename) {
|
|
6081
|
+
function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, warnings) {
|
|
5986
6082
|
const { rawFilename } = zipEntry;
|
|
6083
|
+
const reject = !warnings;
|
|
5987
6084
|
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
5988
6085
|
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
5989
6086
|
if (checkLocalFilename && !maskedLocalDirectory &&
|
|
5990
6087
|
(rawLocalFilename.length != rawFilename.length ||
|
|
5991
6088
|
rawLocalFilename.some((byteValue, indexByte) => byteValue != rawFilename[indexByte]))) {
|
|
5992
|
-
|
|
6089
|
+
reportAmbiguity(reject, warnings, "mismatched local file header (filename)");
|
|
5993
6090
|
}
|
|
5994
6091
|
if ((localDirectory.rawBitFlag & BITFLAG_AMBIGUITY_MASK) != (zipEntry.rawBitFlag & BITFLAG_AMBIGUITY_MASK)) {
|
|
5995
|
-
|
|
6092
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG);
|
|
5996
6093
|
}
|
|
5997
6094
|
if (localDirectory.compressionMethod != zipEntry.compressionMethod) {
|
|
5998
|
-
|
|
6095
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD);
|
|
5999
6096
|
}
|
|
6000
6097
|
if (!localDirectory.bitFlag.dataDescriptor && !maskedLocalDirectory &&
|
|
6001
6098
|
(localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
|
|
6002
6099
|
(localDirectory.crc32 != zipEntry.crc32 ||
|
|
6003
6100
|
localDirectory.compressedSize != zipEntry.compressedSize ||
|
|
6004
6101
|
localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6005
|
-
|
|
6102
|
+
reportAmbiguity(reject, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6103
|
+
}
|
|
6104
|
+
}
|
|
6105
|
+
|
|
6106
|
+
function reportAmbiguity(reject, warnings, reason) {
|
|
6107
|
+
if (reject) {
|
|
6108
|
+
throwAmbiguousArchive(reason);
|
|
6109
|
+
} else {
|
|
6110
|
+
addWarning(warnings, reason);
|
|
6111
|
+
}
|
|
6112
|
+
}
|
|
6113
|
+
|
|
6114
|
+
function addWarning(warnings, reason, filename) {
|
|
6115
|
+
if (!warnings.some(warning => warning.reason == reason)) {
|
|
6116
|
+
const warning = { reason };
|
|
6117
|
+
if (filename !== UNDEFINED_VALUE) {
|
|
6118
|
+
warning.filename = filename;
|
|
6119
|
+
}
|
|
6120
|
+
warnings.push(warning);
|
|
6006
6121
|
}
|
|
6007
6122
|
}
|
|
6008
6123
|
|
|
@@ -6023,7 +6138,8 @@
|
|
|
6023
6138
|
|
|
6024
6139
|
function getDate(timeRaw) {
|
|
6025
6140
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
6026
|
-
|
|
6141
|
+
const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
6142
|
+
return result < MIN_DATE ? MIN_DATE : result;
|
|
6027
6143
|
}
|
|
6028
6144
|
|
|
6029
6145
|
function getDateNTFS(timeRaw) {
|
|
@@ -6078,8 +6194,23 @@
|
|
|
6078
6194
|
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
6079
6195
|
ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
|
|
6080
6196
|
ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
|
|
6197
|
+
WARNING_APPENDED_DATA: WARNING_APPENDED_DATA,
|
|
6198
|
+
WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
|
|
6199
|
+
WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
|
|
6200
|
+
WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
|
|
6201
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6202
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6203
|
+
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6204
|
+
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6205
|
+
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
6206
|
+
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA: WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
6207
|
+
WARNING_UNKNOWN_VERSION: WARNING_UNKNOWN_VERSION,
|
|
6208
|
+
WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA: WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA,
|
|
6209
|
+
WARNING_UNSORTED_CENTRAL_DIRECTORY: WARNING_UNSORTED_CENTRAL_DIRECTORY,
|
|
6210
|
+
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6081
6211
|
ZipReader: ZipReader,
|
|
6082
|
-
ZipReaderStream: ZipReaderStream
|
|
6212
|
+
ZipReaderStream: ZipReaderStream,
|
|
6213
|
+
isZipFile: isZipFile
|
|
6083
6214
|
});
|
|
6084
6215
|
|
|
6085
6216
|
/*
|
|
@@ -6176,153 +6307,151 @@
|
|
|
6176
6307
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
6177
6308
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6178
6309
|
pendingAddFileCalls: new Set(),
|
|
6310
|
+
pendingErrors: [],
|
|
6179
6311
|
bufferedWrites: 0,
|
|
6180
6312
|
lastFileEntry: UNDEFINED_VALUE
|
|
6181
6313
|
});
|
|
6182
6314
|
}
|
|
6183
6315
|
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6191
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6192
|
-
await initStream(reader);
|
|
6193
|
-
}
|
|
6194
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6195
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6196
|
-
const entries = await zipReader$1.getEntries();
|
|
6197
|
-
await zipReader$1.close();
|
|
6198
|
-
await initStream(this.writer);
|
|
6199
|
-
const { directoryOffset } = zipReader$1;
|
|
6200
|
-
if (this.addSplitZipSignature) {
|
|
6201
|
-
delete this.addSplitZipSignature;
|
|
6202
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6203
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6204
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6205
|
-
}
|
|
6206
|
-
}
|
|
6207
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
6208
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
6209
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
6210
|
-
const {
|
|
6211
|
-
version,
|
|
6212
|
-
rawLastModDate,
|
|
6213
|
-
lastAccessDate,
|
|
6214
|
-
creationDate,
|
|
6215
|
-
rawFilename,
|
|
6216
|
-
bitFlag,
|
|
6217
|
-
encrypted,
|
|
6218
|
-
uncompressedSize,
|
|
6219
|
-
compressedSize,
|
|
6220
|
-
extraFieldZip64
|
|
6221
|
-
} = entry;
|
|
6222
|
-
let {
|
|
6223
|
-
compressionMethod,
|
|
6224
|
-
rawExtraFieldZip64,
|
|
6225
|
-
rawExtraFieldAES,
|
|
6226
|
-
rawExtraFieldExtendedTimestamp,
|
|
6227
|
-
rawExtraFieldNTFS,
|
|
6228
|
-
rawExtraFieldUnix,
|
|
6229
|
-
rawExtraField,
|
|
6230
|
-
} = entry;
|
|
6231
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6232
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
6233
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
6234
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
6235
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
6236
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
6237
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6238
|
-
if (entry.extraFieldAES) {
|
|
6239
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6240
|
-
}
|
|
6241
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6242
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6243
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6244
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6245
|
-
const {
|
|
6246
|
-
headerArray,
|
|
6247
|
-
headerView
|
|
6248
|
-
} = getHeaderArrayData({
|
|
6249
|
-
version,
|
|
6250
|
-
bitFlag: bitFlagValue,
|
|
6251
|
-
compressionMethod,
|
|
6252
|
-
uncompressedSize,
|
|
6253
|
-
compressedSize,
|
|
6254
|
-
rawLastModDate,
|
|
6255
|
-
rawFilename,
|
|
6256
|
-
zip64CompressedSize,
|
|
6257
|
-
zip64UncompressedSize,
|
|
6258
|
-
extraFieldLength
|
|
6259
|
-
});
|
|
6260
|
-
const { crc32 } = entry;
|
|
6261
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6262
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6263
|
-
}
|
|
6264
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6265
|
-
Object.assign(entry, {
|
|
6266
|
-
zip64UncompressedSize,
|
|
6267
|
-
zip64CompressedSize,
|
|
6268
|
-
offset,
|
|
6269
|
-
diskNumberStart,
|
|
6270
|
-
zip64DiskNumberStart: false,
|
|
6271
|
-
rawExtraFieldZip64,
|
|
6272
|
-
rawExtraFieldAES,
|
|
6273
|
-
rawExtraFieldExtendedTimestamp,
|
|
6274
|
-
rawExtraFieldNTFS,
|
|
6275
|
-
rawExtraFieldUnix,
|
|
6276
|
-
rawExtraField,
|
|
6277
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
6278
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
6279
|
-
headerArray,
|
|
6280
|
-
headerView
|
|
6281
|
-
});
|
|
6282
|
-
return [entry.filename, entry];
|
|
6283
|
-
}));
|
|
6316
|
+
prependZip(reader) {
|
|
6317
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
6318
|
+
}
|
|
6319
|
+
|
|
6320
|
+
appendZip(reader) {
|
|
6321
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
6284
6322
|
}
|
|
6285
6323
|
|
|
6286
|
-
async
|
|
6324
|
+
async appendZipEntries(reader) {
|
|
6287
6325
|
const zipWriter = this;
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
workers++;
|
|
6292
|
-
} else {
|
|
6293
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6326
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6327
|
+
while (pendingAddFileCalls.size) {
|
|
6328
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6294
6329
|
}
|
|
6295
|
-
let
|
|
6296
|
-
|
|
6330
|
+
let resolveAppendZip;
|
|
6331
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6332
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6333
|
+
const appendedFilenames = [];
|
|
6334
|
+
let releaseLockWriter;
|
|
6297
6335
|
try {
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
}
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6336
|
+
reader = new GenericReader(reader);
|
|
6337
|
+
await initStream(reader);
|
|
6338
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6339
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6340
|
+
await initStream(reader);
|
|
6341
|
+
}
|
|
6342
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6343
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6344
|
+
const entries = await zipReader$1.getEntries();
|
|
6345
|
+
await zipReader$1.close();
|
|
6346
|
+
await initStream(zipWriter.writer);
|
|
6347
|
+
const { directoryOffset } = zipReader$1;
|
|
6348
|
+
entries.forEach(({ filename }) => {
|
|
6349
|
+
if (filenames.has(filename)) {
|
|
6350
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6351
|
+
}
|
|
6352
|
+
filenames.add(filename);
|
|
6353
|
+
appendedFilenames.push(filename);
|
|
6354
|
+
});
|
|
6355
|
+
zipWriter.writerLocked = true;
|
|
6356
|
+
const { lockWriter } = zipWriter;
|
|
6357
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6358
|
+
zipWriter.writerLocked = false;
|
|
6359
|
+
resolve();
|
|
6360
|
+
});
|
|
6361
|
+
await lockWriter;
|
|
6362
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6363
|
+
delete zipWriter.addSplitZipSignature;
|
|
6364
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6365
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6366
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6367
|
+
}
|
|
6313
6368
|
}
|
|
6369
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
6370
|
+
entries.forEach(entry => {
|
|
6371
|
+
const {
|
|
6372
|
+
version,
|
|
6373
|
+
rawLastModDate,
|
|
6374
|
+
rawFilename,
|
|
6375
|
+
bitFlag,
|
|
6376
|
+
encrypted,
|
|
6377
|
+
uncompressedSize,
|
|
6378
|
+
compressedSize,
|
|
6379
|
+
extraFieldZip64
|
|
6380
|
+
} = entry;
|
|
6381
|
+
let {
|
|
6382
|
+
compressionMethod,
|
|
6383
|
+
rawExtraField,
|
|
6384
|
+
} = entry;
|
|
6385
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6386
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6387
|
+
if (entry.extraFieldAES) {
|
|
6388
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6389
|
+
}
|
|
6390
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6391
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6392
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6393
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6394
|
+
const {
|
|
6395
|
+
headerArray,
|
|
6396
|
+
headerView
|
|
6397
|
+
} = getHeaderArrayData({
|
|
6398
|
+
version,
|
|
6399
|
+
bitFlag: bitFlagValue,
|
|
6400
|
+
compressionMethod,
|
|
6401
|
+
uncompressedSize,
|
|
6402
|
+
compressedSize,
|
|
6403
|
+
rawLastModDate,
|
|
6404
|
+
rawFilename,
|
|
6405
|
+
zip64CompressedSize,
|
|
6406
|
+
zip64UncompressedSize,
|
|
6407
|
+
extraFieldLength
|
|
6408
|
+
});
|
|
6409
|
+
const { crc32 } = entry;
|
|
6410
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6411
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6412
|
+
}
|
|
6413
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6414
|
+
Object.assign(entry, {
|
|
6415
|
+
zip64UncompressedSize,
|
|
6416
|
+
zip64CompressedSize,
|
|
6417
|
+
offset,
|
|
6418
|
+
diskNumberStart,
|
|
6419
|
+
zip64DiskNumberStart: false,
|
|
6420
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6421
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6422
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6423
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6424
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6425
|
+
rawExtraField,
|
|
6426
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6427
|
+
extendedTimestamp: false,
|
|
6428
|
+
headerArray,
|
|
6429
|
+
headerView
|
|
6430
|
+
});
|
|
6431
|
+
fileEntries.set(entry.filename, entry);
|
|
6432
|
+
});
|
|
6433
|
+
} catch (error) {
|
|
6434
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6314
6435
|
throw error;
|
|
6315
6436
|
} finally {
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
if (
|
|
6319
|
-
|
|
6320
|
-
} else {
|
|
6321
|
-
workers--;
|
|
6437
|
+
resolveAppendZip();
|
|
6438
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6439
|
+
if (releaseLockWriter) {
|
|
6440
|
+
releaseLockWriter();
|
|
6322
6441
|
}
|
|
6323
6442
|
}
|
|
6324
6443
|
}
|
|
6325
6444
|
|
|
6445
|
+
add(name = "", reader, options = {}) {
|
|
6446
|
+
const zipWriter = this;
|
|
6447
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6448
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
6449
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
6450
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
6451
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
6452
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
6453
|
+
}
|
|
6454
|
+
|
|
6326
6455
|
remove(entry) {
|
|
6327
6456
|
const { filenames, fileEntries } = this;
|
|
6328
6457
|
// deno-lint-ignore valid-typeof
|
|
@@ -6353,6 +6482,19 @@
|
|
|
6353
6482
|
while (pendingAddFileCalls.size) {
|
|
6354
6483
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6355
6484
|
}
|
|
6485
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
6486
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
6487
|
+
if (unobservedWatchers.length) {
|
|
6488
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
6489
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
6490
|
+
const [error] = unobservedErrors;
|
|
6491
|
+
try {
|
|
6492
|
+
error.entryErrors = unobservedErrors;
|
|
6493
|
+
} catch {
|
|
6494
|
+
// ignored
|
|
6495
|
+
}
|
|
6496
|
+
throw error;
|
|
6497
|
+
}
|
|
6356
6498
|
await closeFile(zipWriter, comment, options);
|
|
6357
6499
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6358
6500
|
if (!preventClose) {
|
|
@@ -6387,11 +6529,7 @@
|
|
|
6387
6529
|
try {
|
|
6388
6530
|
await zipWriter.close();
|
|
6389
6531
|
} catch (error) {
|
|
6390
|
-
|
|
6391
|
-
await zipWriter.writer.writable.abort(error);
|
|
6392
|
-
} catch {
|
|
6393
|
-
// ignored
|
|
6394
|
-
}
|
|
6532
|
+
await abortWritable(zipWriter, error);
|
|
6395
6533
|
}
|
|
6396
6534
|
}
|
|
6397
6535
|
}
|
|
@@ -6408,8 +6546,89 @@
|
|
|
6408
6546
|
}
|
|
6409
6547
|
|
|
6410
6548
|
async close(comment = UNDEFINED_VALUE, options = {}) {
|
|
6411
|
-
|
|
6412
|
-
|
|
6549
|
+
const { zipWriter } = this;
|
|
6550
|
+
const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
|
|
6551
|
+
const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
|
|
6552
|
+
if (entryErrors.length) {
|
|
6553
|
+
const [error] = entryErrors;
|
|
6554
|
+
try {
|
|
6555
|
+
error.entryErrors = entryErrors;
|
|
6556
|
+
} catch {
|
|
6557
|
+
// ignored
|
|
6558
|
+
}
|
|
6559
|
+
await abortWritable(zipWriter, error);
|
|
6560
|
+
throw error;
|
|
6561
|
+
}
|
|
6562
|
+
try {
|
|
6563
|
+
return await zipWriter.close(comment, options);
|
|
6564
|
+
} catch (error) {
|
|
6565
|
+
await abortWritable(zipWriter, error);
|
|
6566
|
+
throw error;
|
|
6567
|
+
}
|
|
6568
|
+
}
|
|
6569
|
+
}
|
|
6570
|
+
|
|
6571
|
+
class WatchedPromise extends Promise {
|
|
6572
|
+
|
|
6573
|
+
then(onFulfilled, onRejected) {
|
|
6574
|
+
const { watcher } = this;
|
|
6575
|
+
if (watcher) {
|
|
6576
|
+
watcher.observed = true;
|
|
6577
|
+
}
|
|
6578
|
+
return super.then(onFulfilled, onRejected);
|
|
6579
|
+
}
|
|
6580
|
+
}
|
|
6581
|
+
|
|
6582
|
+
function watchPromiseError(zipWriter, promise) {
|
|
6583
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6584
|
+
const watcher = {};
|
|
6585
|
+
watchedPromise.watcher = watcher;
|
|
6586
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
6587
|
+
zipWriter.pendingErrors.push(watcher);
|
|
6588
|
+
return watchedPromise;
|
|
6589
|
+
}
|
|
6590
|
+
|
|
6591
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
6592
|
+
if (zipWriter.filenames.size) {
|
|
6593
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6594
|
+
}
|
|
6595
|
+
await zipWriter.appendZipEntries(reader);
|
|
6596
|
+
}
|
|
6597
|
+
|
|
6598
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6599
|
+
options = Object.assign({}, options);
|
|
6600
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6601
|
+
name += DIRECTORY_SIGNATURE;
|
|
6602
|
+
}
|
|
6603
|
+
if (zipWriter.filenames.has(name)) {
|
|
6604
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6605
|
+
}
|
|
6606
|
+
zipWriter.filenames.add(name);
|
|
6607
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6608
|
+
workers++;
|
|
6609
|
+
} else {
|
|
6610
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6611
|
+
}
|
|
6612
|
+
try {
|
|
6613
|
+
return await addFile(zipWriter, name, reader, options);
|
|
6614
|
+
} catch (error) {
|
|
6615
|
+
zipWriter.filenames.delete(name);
|
|
6616
|
+
throw error;
|
|
6617
|
+
} finally {
|
|
6618
|
+
const pendingEntry = pendingEntries.shift();
|
|
6619
|
+
if (pendingEntry) {
|
|
6620
|
+
pendingEntry();
|
|
6621
|
+
} else {
|
|
6622
|
+
workers--;
|
|
6623
|
+
}
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
|
|
6627
|
+
async function abortWritable(zipWriter, error) {
|
|
6628
|
+
try {
|
|
6629
|
+
await zipWriter.writer.writable.abort(error);
|
|
6630
|
+
} catch {
|
|
6631
|
+
// ignored
|
|
6413
6632
|
}
|
|
6414
6633
|
}
|
|
6415
6634
|
|
|
@@ -6468,7 +6687,6 @@
|
|
|
6468
6687
|
}
|
|
6469
6688
|
|
|
6470
6689
|
function resolveAttributes(zipWriter, name, options) {
|
|
6471
|
-
name = name.trim();
|
|
6472
6690
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
6473
6691
|
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
6474
6692
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
@@ -6612,11 +6830,12 @@
|
|
|
6612
6830
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
6613
6831
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
6614
6832
|
}
|
|
6615
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
6616
|
-
if (version > MAX_16_BITS) {
|
|
6833
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
6834
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
6617
6835
|
throw new Error(ERR_INVALID_VERSION);
|
|
6618
6836
|
}
|
|
6619
6837
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6838
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
6620
6839
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6621
6840
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6622
6841
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -6660,7 +6879,7 @@
|
|
|
6660
6879
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6661
6880
|
dataDescriptor = false;
|
|
6662
6881
|
}
|
|
6663
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
6882
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
6664
6883
|
dataDescriptor = true;
|
|
6665
6884
|
}
|
|
6666
6885
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6672,6 +6891,7 @@
|
|
|
6672
6891
|
}
|
|
6673
6892
|
const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
|
|
6674
6893
|
const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
|
|
6894
|
+
const rawCentralExtraField = serializeExtraField(options[OPTION_CENTRAL_EXTRA_FIELD]);
|
|
6675
6895
|
return {
|
|
6676
6896
|
comment,
|
|
6677
6897
|
resolvedOptions: {
|
|
@@ -6679,6 +6899,7 @@
|
|
|
6679
6899
|
rawComment,
|
|
6680
6900
|
version,
|
|
6681
6901
|
lastModDate,
|
|
6902
|
+
rawLastModDate,
|
|
6682
6903
|
lastAccessDate,
|
|
6683
6904
|
creationDate,
|
|
6684
6905
|
internalFileAttributes,
|
|
@@ -6706,7 +6927,8 @@
|
|
|
6706
6927
|
dataDescriptor,
|
|
6707
6928
|
zip64,
|
|
6708
6929
|
rawExtraField,
|
|
6709
|
-
rawLocalExtraField
|
|
6930
|
+
rawLocalExtraField,
|
|
6931
|
+
rawCentralExtraField
|
|
6710
6932
|
}
|
|
6711
6933
|
};
|
|
6712
6934
|
}
|
|
@@ -6875,10 +7097,8 @@
|
|
|
6875
7097
|
}
|
|
6876
7098
|
await initStream(fileWriter);
|
|
6877
7099
|
const diskOffset = getDiskOffset(writer);
|
|
6878
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6879
|
-
|
|
6880
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
6881
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
7100
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
7101
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6882
7102
|
}
|
|
6883
7103
|
if (usdz && !bufferedWrite) {
|
|
6884
7104
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6905,6 +7125,9 @@
|
|
|
6905
7125
|
if (bufferedWrite) {
|
|
6906
7126
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
6907
7127
|
await requestLockWriter();
|
|
7128
|
+
if (zipWriter.addSplitZipSignature) {
|
|
7129
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
7130
|
+
}
|
|
6908
7131
|
writingBufferedEntryData = true;
|
|
6909
7132
|
writerSizeBeforeEntry = writer.size;
|
|
6910
7133
|
await skipDiskIfNeeded();
|
|
@@ -7024,6 +7247,7 @@
|
|
|
7024
7247
|
versionMadeBy,
|
|
7025
7248
|
rawComment,
|
|
7026
7249
|
rawExtraField,
|
|
7250
|
+
rawCentralExtraField,
|
|
7027
7251
|
useWebWorkers,
|
|
7028
7252
|
transferStreams,
|
|
7029
7253
|
onstart,
|
|
@@ -7067,6 +7291,7 @@
|
|
|
7067
7291
|
rawExtraFieldUnix,
|
|
7068
7292
|
rawExtraFieldAES,
|
|
7069
7293
|
rawExtraField,
|
|
7294
|
+
rawCentralExtraField,
|
|
7070
7295
|
extendedTimestamp,
|
|
7071
7296
|
msDosCompatible,
|
|
7072
7297
|
internalFileAttributes,
|
|
@@ -7176,6 +7401,7 @@
|
|
|
7176
7401
|
const {
|
|
7177
7402
|
rawFilename,
|
|
7178
7403
|
lastModDate,
|
|
7404
|
+
rawLastModDate: rawLastModDateOption,
|
|
7179
7405
|
lastAccessDate,
|
|
7180
7406
|
creationDate,
|
|
7181
7407
|
level,
|
|
@@ -7309,6 +7535,9 @@
|
|
|
7309
7535
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
7310
7536
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
7311
7537
|
}
|
|
7538
|
+
if (version === UNDEFINED_VALUE) {
|
|
7539
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
7540
|
+
}
|
|
7312
7541
|
const { codecVersionNeeded } = options;
|
|
7313
7542
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
7314
7543
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -7341,6 +7570,7 @@
|
|
|
7341
7570
|
compressionMethod,
|
|
7342
7571
|
uncompressedSize,
|
|
7343
7572
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
7573
|
+
rawLastModDate: rawLastModDateOption,
|
|
7344
7574
|
rawFilename,
|
|
7345
7575
|
zip64CompressedSize,
|
|
7346
7576
|
zip64UncompressedSize,
|
|
@@ -7547,9 +7777,9 @@
|
|
|
7547
7777
|
|
|
7548
7778
|
async function closeFile(zipWriter, comment, options) {
|
|
7549
7779
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7550
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7780
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7551
7781
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7552
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
7782
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
7553
7783
|
}
|
|
7554
7784
|
|
|
7555
7785
|
function createDirectoryRecords(files) {
|
|
@@ -7562,6 +7792,7 @@
|
|
|
7562
7792
|
rawExtraFieldNTFS,
|
|
7563
7793
|
rawExtraFieldUnix,
|
|
7564
7794
|
rawExtraField,
|
|
7795
|
+
rawCentralExtraField,
|
|
7565
7796
|
extendedTimestamp,
|
|
7566
7797
|
extraFieldExtendedTimestampFlag,
|
|
7567
7798
|
lastModDate,
|
|
@@ -7616,7 +7847,8 @@
|
|
|
7616
7847
|
rawExtraFieldNTFS,
|
|
7617
7848
|
rawExtraFieldUnix,
|
|
7618
7849
|
rawExtraFieldTimestamp,
|
|
7619
|
-
rawExtraField
|
|
7850
|
+
rawExtraField,
|
|
7851
|
+
rawCentralExtraField);
|
|
7620
7852
|
if (extraFieldLength > MAX_16_BITS) {
|
|
7621
7853
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
7622
7854
|
}
|
|
@@ -7633,6 +7865,7 @@
|
|
|
7633
7865
|
let directoryDiskOffset = 0;
|
|
7634
7866
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7635
7867
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7868
|
+
let directoryEndDiskEntriesLength = 0;
|
|
7636
7869
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7637
7870
|
const {
|
|
7638
7871
|
offset: fileEntryOffset,
|
|
@@ -7643,6 +7876,7 @@
|
|
|
7643
7876
|
rawExtraFieldNTFS,
|
|
7644
7877
|
rawExtraFieldUnix,
|
|
7645
7878
|
rawExtraField,
|
|
7879
|
+
rawCentralExtraField,
|
|
7646
7880
|
rawComment,
|
|
7647
7881
|
versionMadeBy,
|
|
7648
7882
|
headerArray,
|
|
@@ -7657,11 +7891,12 @@
|
|
|
7657
7891
|
uncompressedSize,
|
|
7658
7892
|
compressedSize
|
|
7659
7893
|
} = fileEntry;
|
|
7660
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
7894
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
|
|
7661
7895
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
7662
7896
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
7663
7897
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
7664
7898
|
directoryDiskOffset = offset;
|
|
7899
|
+
directoryEndDiskEntriesLength = 0;
|
|
7665
7900
|
await writer.closeDisk();
|
|
7666
7901
|
}
|
|
7667
7902
|
if (indexFileEntry == 0) {
|
|
@@ -7694,9 +7929,11 @@
|
|
|
7694
7929
|
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
7695
7930
|
directoryRecord.writeBytes(rawExtraFieldUnix);
|
|
7696
7931
|
directoryRecord.writeBytes(rawExtraField);
|
|
7932
|
+
directoryRecord.writeBytes(rawCentralExtraField);
|
|
7697
7933
|
directoryRecord.writeBytes(rawComment);
|
|
7698
7934
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7699
7935
|
offset += directoryRecordLength;
|
|
7936
|
+
directoryEndDiskEntriesLength++;
|
|
7700
7937
|
if (options.onprogress) {
|
|
7701
7938
|
try {
|
|
7702
7939
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -7708,6 +7945,7 @@
|
|
|
7708
7945
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
7709
7946
|
return {
|
|
7710
7947
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
7948
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
7711
7949
|
directoryArray
|
|
7712
7950
|
};
|
|
7713
7951
|
}
|
|
@@ -7736,16 +7974,20 @@
|
|
|
7736
7974
|
|
|
7737
7975
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
7738
7976
|
const { writer } = zipWriter;
|
|
7739
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
7977
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
7740
7978
|
let { directoryDataLength } = cdInfo;
|
|
7741
7979
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7742
7980
|
let diskNumber = directoryStart.diskNumber;
|
|
7743
7981
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7982
|
+
const commentLength = getLength(comment);
|
|
7983
|
+
if (commentLength > MAX_16_BITS) {
|
|
7984
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
7985
|
+
}
|
|
7986
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7744
7987
|
let lastDiskNumber = getDiskNumber(writer);
|
|
7745
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
7988
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
7746
7989
|
lastDiskNumber++;
|
|
7747
7990
|
}
|
|
7748
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7749
7991
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7750
7992
|
if (zip64 === false) {
|
|
7751
7993
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -7753,15 +7995,12 @@
|
|
|
7753
7995
|
zip64 = true;
|
|
7754
7996
|
}
|
|
7755
7997
|
}
|
|
7756
|
-
const commentLength = getLength(comment);
|
|
7757
|
-
if (commentLength > MAX_16_BITS) {
|
|
7758
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
7759
|
-
}
|
|
7760
7998
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7761
7999
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
7762
8000
|
await writer.closeDisk();
|
|
7763
8001
|
}
|
|
7764
8002
|
lastDiskNumber = getDiskNumber(writer);
|
|
8003
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
7765
8004
|
if (zip64) {
|
|
7766
8005
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7767
8006
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -7769,7 +8008,7 @@
|
|
|
7769
8008
|
endOfdirectoryRecord.writeUint16(45);
|
|
7770
8009
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7771
8010
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7772
|
-
endOfdirectoryRecord.writeUint64(
|
|
8011
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
7773
8012
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7774
8013
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7775
8014
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -7782,6 +8021,7 @@
|
|
|
7782
8021
|
lastDiskNumber = MAX_16_BITS;
|
|
7783
8022
|
diskNumber = MAX_16_BITS;
|
|
7784
8023
|
}
|
|
8024
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
7785
8025
|
fileEntriesLength = MAX_16_BITS;
|
|
7786
8026
|
directoryOffset = MAX_32_BITS;
|
|
7787
8027
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -7789,7 +8029,7 @@
|
|
|
7789
8029
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7790
8030
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7791
8031
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7792
|
-
endOfdirectoryRecord.writeUint16(
|
|
8032
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
7793
8033
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7794
8034
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7795
8035
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -7888,9 +8128,21 @@
|
|
|
7888
8128
|
async function copyData(zipWriter, reader, offset, size) {
|
|
7889
8129
|
if (size > 0) {
|
|
7890
8130
|
const { writer } = zipWriter;
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
8131
|
+
let copiedLength = 0;
|
|
8132
|
+
try {
|
|
8133
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8134
|
+
} catch (error) {
|
|
8135
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8136
|
+
try {
|
|
8137
|
+
error.corruptedEntry = true;
|
|
8138
|
+
} catch {
|
|
8139
|
+
// ignored
|
|
8140
|
+
}
|
|
8141
|
+
throw error;
|
|
8142
|
+
} finally {
|
|
8143
|
+
writer.size += copiedLength;
|
|
8144
|
+
zipWriter.offset += copiedLength;
|
|
8145
|
+
}
|
|
7894
8146
|
}
|
|
7895
8147
|
}
|
|
7896
8148
|
|
|
@@ -7915,6 +8167,12 @@
|
|
|
7915
8167
|
return signatureArray;
|
|
7916
8168
|
}
|
|
7917
8169
|
|
|
8170
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
8171
|
+
delete zipWriter.addSplitZipSignature;
|
|
8172
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
8173
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
8174
|
+
}
|
|
8175
|
+
|
|
7918
8176
|
async function writeData(writer, array) {
|
|
7919
8177
|
const { writable } = writer;
|
|
7920
8178
|
const streamWriter = writable.getWriter();
|
|
@@ -8675,6 +8933,20 @@
|
|
|
8675
8933
|
exports.TextWriter = TextWriter;
|
|
8676
8934
|
exports.Uint8ArrayReader = Uint8ArrayReader;
|
|
8677
8935
|
exports.Uint8ArrayWriter = Uint8ArrayWriter;
|
|
8936
|
+
exports.WARNING_APPENDED_DATA = WARNING_APPENDED_DATA;
|
|
8937
|
+
exports.WARNING_COMPRESSED_PATCHED_DATA = WARNING_COMPRESSED_PATCHED_DATA;
|
|
8938
|
+
exports.WARNING_DUPLICATE_FILENAME = WARNING_DUPLICATE_FILENAME;
|
|
8939
|
+
exports.WARNING_MALFORMED_EXTRA_FIELD = WARNING_MALFORMED_EXTRA_FIELD;
|
|
8940
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG = WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG;
|
|
8941
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD;
|
|
8942
|
+
exports.WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES;
|
|
8943
|
+
exports.WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY;
|
|
8944
|
+
exports.WARNING_PREPENDED_DATA = WARNING_PREPENDED_DATA;
|
|
8945
|
+
exports.WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = WARNING_TRAILING_CENTRAL_DIRECTORY_DATA;
|
|
8946
|
+
exports.WARNING_UNKNOWN_VERSION = WARNING_UNKNOWN_VERSION;
|
|
8947
|
+
exports.WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA = WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA;
|
|
8948
|
+
exports.WARNING_UNSORTED_CENTRAL_DIRECTORY = WARNING_UNSORTED_CENTRAL_DIRECTORY;
|
|
8949
|
+
exports.WARNING_WRAPPED_ENTRIES_COUNT = WARNING_WRAPPED_ENTRIES_COUNT;
|
|
8678
8950
|
exports.Writer = Writer;
|
|
8679
8951
|
exports.ZipReader = ZipReader;
|
|
8680
8952
|
exports.ZipReaderStream = ZipReaderStream;
|
|
@@ -8685,6 +8957,7 @@
|
|
|
8685
8957
|
exports.createOPFSTempStream = createOPFSTempStream;
|
|
8686
8958
|
exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
|
|
8687
8959
|
exports.getMimeType = getMimeType;
|
|
8960
|
+
exports.isZipFile = isZipFile;
|
|
8688
8961
|
exports.registerCodec = registerCodec;
|
|
8689
8962
|
exports.resetConfiguration = resetConfiguration;
|
|
8690
8963
|
exports.terminateWorkers = terminateWorkers;
|