@zip.js/zip.js 2.8.56 → 2.8.58
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 +346 -182
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +346 -181
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +370 -183
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +387 -176
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +370 -183
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +373 -184
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +374 -185
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +348 -183
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +348 -183
- 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 +349 -184
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +373 -184
- package/index-native.min.js +1 -1
- package/index.cjs +374 -185
- package/index.d.cts +126 -10
- package/index.d.ts +126 -10
- package/index.min.js +1 -1
- package/lib/core/constants.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 +28 -2
- package/lib/core/zip-reader.js +37 -10
- package/lib/core/zip-writer.js +311 -172
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-core-reader.js +1 -0
- package/package.json +1 -1
package/dist/zip-core.js
CHANGED
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
|
|
102
102
|
const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
|
|
103
103
|
|
|
104
|
+
const VERSION_STORE = 0x0A;
|
|
104
105
|
const VERSION_DEFLATE = 0x14;
|
|
105
106
|
const VERSION_ZIP64 = 0x2D;
|
|
106
107
|
const VERSION_AES = 0x33;
|
|
@@ -4707,6 +4708,7 @@
|
|
|
4707
4708
|
const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
|
|
4708
4709
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
4709
4710
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
4711
|
+
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
4710
4712
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4711
4713
|
const CHARSET_UTF8 = "utf-8";
|
|
4712
4714
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -4729,6 +4731,7 @@
|
|
|
4729
4731
|
bytes: 8
|
|
4730
4732
|
}
|
|
4731
4733
|
};
|
|
4734
|
+
const MAX_SAFE_UINT64 = BigInt(Number.MAX_SAFE_INTEGER);
|
|
4732
4735
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4733
4736
|
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4734
4737
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
@@ -4824,7 +4827,7 @@
|
|
|
4824
4827
|
zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
|
|
4825
4828
|
if (zip64EndOfDirectoryVersion2) {
|
|
4826
4829
|
const extensibleDataLength = Math.min(
|
|
4827
|
-
|
|
4830
|
+
getBigUint64(endOfDirectoryView, 4) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
|
|
4828
4831
|
reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4829
4832
|
if (extensibleDataLength > 0) {
|
|
4830
4833
|
zip64EndOfDirectoryLength += extensibleDataLength;
|
|
@@ -4924,6 +4927,10 @@
|
|
|
4924
4927
|
const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
|
|
4925
4928
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4926
4929
|
let duplicateFilename;
|
|
4930
|
+
const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
|
|
4931
|
+
if (!filesLength && recoverWrappedFilesLength) {
|
|
4932
|
+
filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4933
|
+
}
|
|
4927
4934
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4928
4935
|
const fileEntry = new ZipEntry(reader, zipReader.options);
|
|
4929
4936
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -5033,7 +5040,7 @@
|
|
|
5033
5040
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
5034
5041
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
5035
5042
|
executable,
|
|
5036
|
-
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) ||
|
|
5043
|
+
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
|
|
5037
5044
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5038
5045
|
});
|
|
5039
5046
|
const entry = new Entry(fileEntry);
|
|
@@ -5046,6 +5053,9 @@
|
|
|
5046
5053
|
return arrayBufferPromise;
|
|
5047
5054
|
};
|
|
5048
5055
|
offset = endOffset;
|
|
5056
|
+
if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
|
|
5057
|
+
filesLength += getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
5058
|
+
}
|
|
5049
5059
|
const { onprogress } = options;
|
|
5050
5060
|
if (onprogress) {
|
|
5051
5061
|
try {
|
|
@@ -5204,6 +5214,7 @@
|
|
|
5204
5214
|
extraFieldLength,
|
|
5205
5215
|
filenameLength
|
|
5206
5216
|
} = localDirectory;
|
|
5217
|
+
const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5207
5218
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
5208
5219
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
5209
5220
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
@@ -5257,7 +5268,6 @@
|
|
|
5257
5268
|
throw new Error(ERR_ENCRYPTED);
|
|
5258
5269
|
}
|
|
5259
5270
|
}
|
|
5260
|
-
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
5261
5271
|
if (dataOffset + compressedSize > reader.size) {
|
|
5262
5272
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5263
5273
|
}
|
|
@@ -5377,6 +5387,16 @@
|
|
|
5377
5387
|
return false;
|
|
5378
5388
|
}
|
|
5379
5389
|
|
|
5390
|
+
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
5391
|
+
let wrappedFilesLength = 0;
|
|
5392
|
+
while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
5393
|
+
offset += CENTRAL_FILE_HEADER_LENGTH +
|
|
5394
|
+
getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
|
|
5395
|
+
wrappedFilesLength++;
|
|
5396
|
+
}
|
|
5397
|
+
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
5398
|
+
}
|
|
5399
|
+
|
|
5380
5400
|
function readDigitalSignature(signatureRecordArray) {
|
|
5381
5401
|
if (signatureRecordArray.length >= 6) {
|
|
5382
5402
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5405,8 +5425,8 @@
|
|
|
5405
5425
|
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
5406
5426
|
Object.assign(directoryEncryptionInfo, {
|
|
5407
5427
|
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
5408
|
-
compressedSize:
|
|
5409
|
-
uncompressedSize:
|
|
5428
|
+
compressedSize: getBigUint64(extensibleDataView, 2),
|
|
5429
|
+
uncompressedSize: getBigUint64(extensibleDataView, 10),
|
|
5410
5430
|
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
5411
5431
|
bitLength: getUint16$1(extensibleDataView, 20),
|
|
5412
5432
|
flags: getUint16$1(extensibleDataView, 22),
|
|
@@ -5549,10 +5569,11 @@
|
|
|
5549
5569
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5550
5570
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5551
5571
|
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
5572
|
+
const version = getUint8(extraFieldView, 0);
|
|
5552
5573
|
Object.assign(extraFieldUnicode, {
|
|
5553
|
-
version
|
|
5574
|
+
version,
|
|
5554
5575
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5555
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5576
|
+
valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
5556
5577
|
});
|
|
5557
5578
|
if (extraFieldUnicode.valid) {
|
|
5558
5579
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -6021,7 +6042,8 @@
|
|
|
6021
6042
|
|
|
6022
6043
|
function getDate(timeRaw) {
|
|
6023
6044
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
6024
|
-
|
|
6045
|
+
const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
6046
|
+
return result < MIN_DATE ? MIN_DATE : result;
|
|
6025
6047
|
}
|
|
6026
6048
|
|
|
6027
6049
|
function getDateNTFS(timeRaw) {
|
|
@@ -6041,7 +6063,11 @@
|
|
|
6041
6063
|
}
|
|
6042
6064
|
|
|
6043
6065
|
function getBigUint64(view, offset) {
|
|
6044
|
-
|
|
6066
|
+
const value = view.getBigUint64(offset, true);
|
|
6067
|
+
if (value > MAX_SAFE_UINT64) {
|
|
6068
|
+
throw new Error(ERR_UNSUPPORTED_UINT64);
|
|
6069
|
+
}
|
|
6070
|
+
return Number(value);
|
|
6045
6071
|
}
|
|
6046
6072
|
|
|
6047
6073
|
var zipReader = /*#__PURE__*/Object.freeze({
|
|
@@ -6070,6 +6096,7 @@
|
|
|
6070
6096
|
ERR_UNSAFE_FILENAME: ERR_UNSAFE_FILENAME,
|
|
6071
6097
|
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
6072
6098
|
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
6099
|
+
ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
|
|
6073
6100
|
ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
|
|
6074
6101
|
ZipReader: ZipReader,
|
|
6075
6102
|
ZipReaderStream: ZipReaderStream
|
|
@@ -6169,153 +6196,150 @@
|
|
|
6169
6196
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
6170
6197
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
6171
6198
|
pendingAddFileCalls: new Set(),
|
|
6199
|
+
pendingErrors: [],
|
|
6172
6200
|
bufferedWrites: 0,
|
|
6173
6201
|
lastFileEntry: UNDEFINED_VALUE
|
|
6174
6202
|
});
|
|
6175
6203
|
}
|
|
6176
6204
|
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6184
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6185
|
-
await initStream(reader);
|
|
6186
|
-
}
|
|
6187
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6188
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6189
|
-
const entries = await zipReader$1.getEntries();
|
|
6190
|
-
await zipReader$1.close();
|
|
6191
|
-
await initStream(this.writer);
|
|
6192
|
-
const { directoryOffset } = zipReader$1;
|
|
6193
|
-
if (this.addSplitZipSignature) {
|
|
6194
|
-
delete this.addSplitZipSignature;
|
|
6195
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6196
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
6197
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6198
|
-
}
|
|
6199
|
-
}
|
|
6200
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
6201
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
6202
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
6203
|
-
const {
|
|
6204
|
-
version,
|
|
6205
|
-
rawLastModDate,
|
|
6206
|
-
lastAccessDate,
|
|
6207
|
-
creationDate,
|
|
6208
|
-
rawFilename,
|
|
6209
|
-
bitFlag,
|
|
6210
|
-
encrypted,
|
|
6211
|
-
uncompressedSize,
|
|
6212
|
-
compressedSize,
|
|
6213
|
-
zip64
|
|
6214
|
-
} = entry;
|
|
6215
|
-
let {
|
|
6216
|
-
compressionMethod,
|
|
6217
|
-
rawExtraFieldZip64,
|
|
6218
|
-
rawExtraFieldAES,
|
|
6219
|
-
rawExtraFieldExtendedTimestamp,
|
|
6220
|
-
rawExtraFieldNTFS,
|
|
6221
|
-
rawExtraFieldUnix,
|
|
6222
|
-
rawExtraField,
|
|
6223
|
-
} = entry;
|
|
6224
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6225
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
6226
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
6227
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
6228
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
6229
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
6230
|
-
rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
|
|
6231
|
-
if (entry.extraFieldAES) {
|
|
6232
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6233
|
-
}
|
|
6234
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6235
|
-
const zip64UncompressedSize = zip64 && uncompressedSize >= MAX_32_BITS;
|
|
6236
|
-
const zip64CompressedSize = zip64 && compressedSize >= MAX_32_BITS;
|
|
6237
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6238
|
-
const {
|
|
6239
|
-
headerArray,
|
|
6240
|
-
headerView
|
|
6241
|
-
} = getHeaderArrayData({
|
|
6242
|
-
version,
|
|
6243
|
-
bitFlag: bitFlagValue,
|
|
6244
|
-
compressionMethod,
|
|
6245
|
-
uncompressedSize,
|
|
6246
|
-
compressedSize,
|
|
6247
|
-
rawLastModDate,
|
|
6248
|
-
rawFilename,
|
|
6249
|
-
zip64CompressedSize,
|
|
6250
|
-
zip64UncompressedSize,
|
|
6251
|
-
extraFieldLength
|
|
6252
|
-
});
|
|
6253
|
-
const { crc32 } = entry;
|
|
6254
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6255
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6256
|
-
}
|
|
6257
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6258
|
-
Object.assign(entry, {
|
|
6259
|
-
zip64UncompressedSize,
|
|
6260
|
-
zip64CompressedSize,
|
|
6261
|
-
offset,
|
|
6262
|
-
diskNumberStart,
|
|
6263
|
-
zip64DiskNumberStart: false,
|
|
6264
|
-
rawExtraFieldZip64,
|
|
6265
|
-
rawExtraFieldAES,
|
|
6266
|
-
rawExtraFieldExtendedTimestamp,
|
|
6267
|
-
rawExtraFieldNTFS,
|
|
6268
|
-
rawExtraFieldUnix,
|
|
6269
|
-
rawExtraField,
|
|
6270
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
6271
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
6272
|
-
headerArray,
|
|
6273
|
-
headerView
|
|
6274
|
-
});
|
|
6275
|
-
return [entry.filename, entry];
|
|
6276
|
-
}));
|
|
6205
|
+
prependZip(reader) {
|
|
6206
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
appendZip(reader) {
|
|
6210
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
6277
6211
|
}
|
|
6278
6212
|
|
|
6279
|
-
async
|
|
6213
|
+
async appendZipEntries(reader) {
|
|
6280
6214
|
const zipWriter = this;
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
workers++;
|
|
6285
|
-
} else {
|
|
6286
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6215
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6216
|
+
while (pendingAddFileCalls.size) {
|
|
6217
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6287
6218
|
}
|
|
6288
|
-
let
|
|
6289
|
-
|
|
6219
|
+
let resolveAppendZip;
|
|
6220
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6221
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6222
|
+
const appendedFilenames = [];
|
|
6223
|
+
let releaseLockWriter;
|
|
6290
6224
|
try {
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
}
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6225
|
+
reader = new GenericReader(reader);
|
|
6226
|
+
await initStream(reader);
|
|
6227
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6228
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6229
|
+
await initStream(reader);
|
|
6230
|
+
}
|
|
6231
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6232
|
+
const zipReader$1 = new ZipReader(reader);
|
|
6233
|
+
const entries = await zipReader$1.getEntries();
|
|
6234
|
+
await zipReader$1.close();
|
|
6235
|
+
await initStream(zipWriter.writer);
|
|
6236
|
+
const { directoryOffset } = zipReader$1;
|
|
6237
|
+
entries.forEach(({ filename }) => {
|
|
6238
|
+
if (filenames.has(filename)) {
|
|
6239
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6240
|
+
}
|
|
6241
|
+
filenames.add(filename);
|
|
6242
|
+
appendedFilenames.push(filename);
|
|
6243
|
+
});
|
|
6244
|
+
zipWriter.writerLocked = true;
|
|
6245
|
+
const { lockWriter } = zipWriter;
|
|
6246
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6247
|
+
zipWriter.writerLocked = false;
|
|
6248
|
+
resolve();
|
|
6249
|
+
});
|
|
6250
|
+
await lockWriter;
|
|
6251
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6252
|
+
delete zipWriter.addSplitZipSignature;
|
|
6253
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
6254
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6255
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6256
|
+
}
|
|
6306
6257
|
}
|
|
6258
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
6259
|
+
entries.forEach(entry => {
|
|
6260
|
+
const {
|
|
6261
|
+
version,
|
|
6262
|
+
rawLastModDate,
|
|
6263
|
+
rawFilename,
|
|
6264
|
+
bitFlag,
|
|
6265
|
+
encrypted,
|
|
6266
|
+
uncompressedSize,
|
|
6267
|
+
compressedSize,
|
|
6268
|
+
extraFieldZip64
|
|
6269
|
+
} = entry;
|
|
6270
|
+
let {
|
|
6271
|
+
compressionMethod,
|
|
6272
|
+
rawExtraField,
|
|
6273
|
+
} = entry;
|
|
6274
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6275
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6276
|
+
if (entry.extraFieldAES) {
|
|
6277
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6278
|
+
}
|
|
6279
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6280
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6281
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6282
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6283
|
+
const {
|
|
6284
|
+
headerArray,
|
|
6285
|
+
headerView
|
|
6286
|
+
} = getHeaderArrayData({
|
|
6287
|
+
version,
|
|
6288
|
+
bitFlag: bitFlagValue,
|
|
6289
|
+
compressionMethod,
|
|
6290
|
+
uncompressedSize,
|
|
6291
|
+
compressedSize,
|
|
6292
|
+
rawLastModDate,
|
|
6293
|
+
rawFilename,
|
|
6294
|
+
zip64CompressedSize,
|
|
6295
|
+
zip64UncompressedSize,
|
|
6296
|
+
extraFieldLength
|
|
6297
|
+
});
|
|
6298
|
+
const { crc32 } = entry;
|
|
6299
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6300
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6301
|
+
}
|
|
6302
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6303
|
+
Object.assign(entry, {
|
|
6304
|
+
zip64UncompressedSize,
|
|
6305
|
+
zip64CompressedSize,
|
|
6306
|
+
offset,
|
|
6307
|
+
diskNumberStart,
|
|
6308
|
+
zip64DiskNumberStart: false,
|
|
6309
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6310
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6311
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6312
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6313
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6314
|
+
rawExtraField,
|
|
6315
|
+
extendedTimestamp: false,
|
|
6316
|
+
headerArray,
|
|
6317
|
+
headerView
|
|
6318
|
+
});
|
|
6319
|
+
fileEntries.set(entry.filename, entry);
|
|
6320
|
+
});
|
|
6321
|
+
} catch (error) {
|
|
6322
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6307
6323
|
throw error;
|
|
6308
6324
|
} finally {
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
if (
|
|
6312
|
-
|
|
6313
|
-
} else {
|
|
6314
|
-
workers--;
|
|
6325
|
+
resolveAppendZip();
|
|
6326
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6327
|
+
if (releaseLockWriter) {
|
|
6328
|
+
releaseLockWriter();
|
|
6315
6329
|
}
|
|
6316
6330
|
}
|
|
6317
6331
|
}
|
|
6318
6332
|
|
|
6333
|
+
add(name = "", reader, options = {}) {
|
|
6334
|
+
const zipWriter = this;
|
|
6335
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
6336
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
6337
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
6338
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
6339
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
6340
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
6341
|
+
}
|
|
6342
|
+
|
|
6319
6343
|
remove(entry) {
|
|
6320
6344
|
const { filenames, fileEntries } = this;
|
|
6321
6345
|
// deno-lint-ignore valid-typeof
|
|
@@ -6346,6 +6370,19 @@
|
|
|
6346
6370
|
while (pendingAddFileCalls.size) {
|
|
6347
6371
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6348
6372
|
}
|
|
6373
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
6374
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
6375
|
+
if (unobservedWatchers.length) {
|
|
6376
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
6377
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
6378
|
+
const [error] = unobservedErrors;
|
|
6379
|
+
try {
|
|
6380
|
+
error.entryErrors = unobservedErrors;
|
|
6381
|
+
} catch {
|
|
6382
|
+
// ignored
|
|
6383
|
+
}
|
|
6384
|
+
throw error;
|
|
6385
|
+
}
|
|
6349
6386
|
await closeFile(zipWriter, comment, options);
|
|
6350
6387
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
6351
6388
|
if (!preventClose) {
|
|
@@ -6380,11 +6417,7 @@
|
|
|
6380
6417
|
try {
|
|
6381
6418
|
await zipWriter.close();
|
|
6382
6419
|
} catch (error) {
|
|
6383
|
-
|
|
6384
|
-
await zipWriter.writer.writable.abort(error);
|
|
6385
|
-
} catch {
|
|
6386
|
-
// ignored
|
|
6387
|
-
}
|
|
6420
|
+
await abortWritable(zipWriter, error);
|
|
6388
6421
|
}
|
|
6389
6422
|
}
|
|
6390
6423
|
}
|
|
@@ -6401,8 +6434,90 @@
|
|
|
6401
6434
|
}
|
|
6402
6435
|
|
|
6403
6436
|
async close(comment = UNDEFINED_VALUE, options = {}) {
|
|
6404
|
-
|
|
6405
|
-
|
|
6437
|
+
const { zipWriter } = this;
|
|
6438
|
+
const results = await Promise.allSettled(Array.from(this.pendingAddFileCalls));
|
|
6439
|
+
const entryErrors = results.filter(result => result.status == "rejected").map(result => result.reason);
|
|
6440
|
+
if (entryErrors.length) {
|
|
6441
|
+
const [error] = entryErrors;
|
|
6442
|
+
try {
|
|
6443
|
+
error.entryErrors = entryErrors;
|
|
6444
|
+
} catch {
|
|
6445
|
+
// ignored
|
|
6446
|
+
}
|
|
6447
|
+
await abortWritable(zipWriter, error);
|
|
6448
|
+
throw error;
|
|
6449
|
+
}
|
|
6450
|
+
try {
|
|
6451
|
+
return await zipWriter.close(comment, options);
|
|
6452
|
+
} catch (error) {
|
|
6453
|
+
await abortWritable(zipWriter, error);
|
|
6454
|
+
throw error;
|
|
6455
|
+
}
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
6458
|
+
|
|
6459
|
+
class WatchedPromise extends Promise {
|
|
6460
|
+
|
|
6461
|
+
then(onFulfilled, onRejected) {
|
|
6462
|
+
const { watcher } = this;
|
|
6463
|
+
if (watcher) {
|
|
6464
|
+
watcher.observed = true;
|
|
6465
|
+
}
|
|
6466
|
+
return super.then(onFulfilled, onRejected);
|
|
6467
|
+
}
|
|
6468
|
+
}
|
|
6469
|
+
|
|
6470
|
+
function watchPromiseError(zipWriter, promise) {
|
|
6471
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
6472
|
+
const watcher = {};
|
|
6473
|
+
watchedPromise.watcher = watcher;
|
|
6474
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
6475
|
+
zipWriter.pendingErrors.push(watcher);
|
|
6476
|
+
return watchedPromise;
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6479
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
6480
|
+
if (zipWriter.filenames.size) {
|
|
6481
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6482
|
+
}
|
|
6483
|
+
await zipWriter.appendZipEntries(reader);
|
|
6484
|
+
}
|
|
6485
|
+
|
|
6486
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
6487
|
+
options = Object.assign({}, options);
|
|
6488
|
+
name = name.trim();
|
|
6489
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
6490
|
+
name += DIRECTORY_SIGNATURE;
|
|
6491
|
+
}
|
|
6492
|
+
if (zipWriter.filenames.has(name)) {
|
|
6493
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6494
|
+
}
|
|
6495
|
+
zipWriter.filenames.add(name);
|
|
6496
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
6497
|
+
workers++;
|
|
6498
|
+
} else {
|
|
6499
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
6500
|
+
}
|
|
6501
|
+
try {
|
|
6502
|
+
return await addFile(zipWriter, name, reader, options);
|
|
6503
|
+
} catch (error) {
|
|
6504
|
+
zipWriter.filenames.delete(name);
|
|
6505
|
+
throw error;
|
|
6506
|
+
} finally {
|
|
6507
|
+
const pendingEntry = pendingEntries.shift();
|
|
6508
|
+
if (pendingEntry) {
|
|
6509
|
+
pendingEntry();
|
|
6510
|
+
} else {
|
|
6511
|
+
workers--;
|
|
6512
|
+
}
|
|
6513
|
+
}
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6516
|
+
async function abortWritable(zipWriter, error) {
|
|
6517
|
+
try {
|
|
6518
|
+
await zipWriter.writer.writable.abort(error);
|
|
6519
|
+
} catch {
|
|
6520
|
+
// ignored
|
|
6406
6521
|
}
|
|
6407
6522
|
}
|
|
6408
6523
|
|
|
@@ -6605,11 +6720,12 @@
|
|
|
6605
6720
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
6606
6721
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
6607
6722
|
}
|
|
6608
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
6609
|
-
if (version > MAX_16_BITS) {
|
|
6723
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
6724
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
6610
6725
|
throw new Error(ERR_INVALID_VERSION);
|
|
6611
6726
|
}
|
|
6612
6727
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6728
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
6613
6729
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
6614
6730
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
6615
6731
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -6653,7 +6769,7 @@
|
|
|
6653
6769
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
6654
6770
|
dataDescriptor = false;
|
|
6655
6771
|
}
|
|
6656
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
6772
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
6657
6773
|
dataDescriptor = true;
|
|
6658
6774
|
}
|
|
6659
6775
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -6672,6 +6788,7 @@
|
|
|
6672
6788
|
rawComment,
|
|
6673
6789
|
version,
|
|
6674
6790
|
lastModDate,
|
|
6791
|
+
rawLastModDate,
|
|
6675
6792
|
lastAccessDate,
|
|
6676
6793
|
creationDate,
|
|
6677
6794
|
internalFileAttributes,
|
|
@@ -6789,6 +6906,10 @@
|
|
|
6789
6906
|
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
6790
6907
|
}
|
|
6791
6908
|
}
|
|
6909
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
|
|
6910
|
+
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
6911
|
+
dataDescriptor = false;
|
|
6912
|
+
}
|
|
6792
6913
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
6793
6914
|
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
6794
6915
|
if (zip64UncompressedSize || zip64CompressedSize) {
|
|
@@ -6803,6 +6924,7 @@
|
|
|
6803
6924
|
maximumCompressedSize,
|
|
6804
6925
|
resolvedOptions: {
|
|
6805
6926
|
dataDescriptor,
|
|
6927
|
+
emptyEntry,
|
|
6806
6928
|
zip64,
|
|
6807
6929
|
zip64UncompressedSize,
|
|
6808
6930
|
zip64CompressedSize,
|
|
@@ -6822,6 +6944,7 @@
|
|
|
6822
6944
|
const {
|
|
6823
6945
|
keepOrder,
|
|
6824
6946
|
dataDescriptor,
|
|
6947
|
+
emptyEntry,
|
|
6825
6948
|
signal
|
|
6826
6949
|
} = options;
|
|
6827
6950
|
const {
|
|
@@ -6846,7 +6969,7 @@
|
|
|
6846
6969
|
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6847
6970
|
requestLockCurrentFileEntry();
|
|
6848
6971
|
}
|
|
6849
|
-
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
6972
|
+
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
|
|
6850
6973
|
bufferedWrite = true;
|
|
6851
6974
|
zipWriter.bufferedWrites++;
|
|
6852
6975
|
if (options.createTempStream) {
|
|
@@ -6862,10 +6985,8 @@
|
|
|
6862
6985
|
}
|
|
6863
6986
|
await initStream(fileWriter);
|
|
6864
6987
|
const diskOffset = getDiskOffset(writer);
|
|
6865
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6866
|
-
|
|
6867
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
6868
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6988
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
6989
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6869
6990
|
}
|
|
6870
6991
|
if (usdz && !bufferedWrite) {
|
|
6871
6992
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6892,6 +7013,9 @@
|
|
|
6892
7013
|
if (bufferedWrite) {
|
|
6893
7014
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
6894
7015
|
await requestLockWriter();
|
|
7016
|
+
if (zipWriter.addSplitZipSignature) {
|
|
7017
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
7018
|
+
}
|
|
6895
7019
|
writingBufferedEntryData = true;
|
|
6896
7020
|
writerSizeBeforeEntry = writer.size;
|
|
6897
7021
|
await skipDiskIfNeeded();
|
|
@@ -7163,6 +7287,7 @@
|
|
|
7163
7287
|
const {
|
|
7164
7288
|
rawFilename,
|
|
7165
7289
|
lastModDate,
|
|
7290
|
+
rawLastModDate: rawLastModDateOption,
|
|
7166
7291
|
lastAccessDate,
|
|
7167
7292
|
creationDate,
|
|
7168
7293
|
level,
|
|
@@ -7268,8 +7393,8 @@
|
|
|
7268
7393
|
try {
|
|
7269
7394
|
const { uid, gid, unixExtraFieldType } = options;
|
|
7270
7395
|
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7271
|
-
const uidBytes = packUnixId(uid);
|
|
7272
|
-
const gidBytes = packUnixId(gid);
|
|
7396
|
+
const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
|
|
7397
|
+
const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
|
|
7273
7398
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
7274
7399
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
7275
7400
|
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
@@ -7296,6 +7421,9 @@
|
|
|
7296
7421
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
7297
7422
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
7298
7423
|
}
|
|
7424
|
+
if (version === UNDEFINED_VALUE) {
|
|
7425
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
7426
|
+
}
|
|
7299
7427
|
const { codecVersionNeeded } = options;
|
|
7300
7428
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
7301
7429
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -7328,6 +7456,7 @@
|
|
|
7328
7456
|
compressionMethod,
|
|
7329
7457
|
uncompressedSize,
|
|
7330
7458
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
7459
|
+
rawLastModDate: rawLastModDateOption,
|
|
7331
7460
|
rawFilename,
|
|
7332
7461
|
zip64CompressedSize,
|
|
7333
7462
|
zip64UncompressedSize,
|
|
@@ -7400,18 +7529,14 @@
|
|
|
7400
7529
|
}
|
|
7401
7530
|
|
|
7402
7531
|
function packUnixId(id) {
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
let length = 4;
|
|
7410
|
-
while (length > 1 && dataArray[length - 1] === 0) {
|
|
7411
|
-
length--;
|
|
7412
|
-
}
|
|
7413
|
-
return dataArray.subarray(0, length);
|
|
7532
|
+
const dataArray = new Uint8Array(4);
|
|
7533
|
+
const dataView = getDataView(dataArray);
|
|
7534
|
+
dataView.setUint32(0, id, true);
|
|
7535
|
+
let length = 4;
|
|
7536
|
+
while (length > 1 && dataArray[length - 1] === 0) {
|
|
7537
|
+
length--;
|
|
7414
7538
|
}
|
|
7539
|
+
return dataArray.subarray(0, length);
|
|
7415
7540
|
}
|
|
7416
7541
|
|
|
7417
7542
|
function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
|
|
@@ -7538,9 +7663,9 @@
|
|
|
7538
7663
|
|
|
7539
7664
|
async function closeFile(zipWriter, comment, options) {
|
|
7540
7665
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
7541
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7666
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7542
7667
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
7543
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
7668
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
7544
7669
|
}
|
|
7545
7670
|
|
|
7546
7671
|
function createDirectoryRecords(files) {
|
|
@@ -7624,6 +7749,7 @@
|
|
|
7624
7749
|
let directoryDiskOffset = 0;
|
|
7625
7750
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7626
7751
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7752
|
+
let directoryEndDiskEntriesLength = 0;
|
|
7627
7753
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7628
7754
|
const {
|
|
7629
7755
|
offset: fileEntryOffset,
|
|
@@ -7653,6 +7779,7 @@
|
|
|
7653
7779
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
7654
7780
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
7655
7781
|
directoryDiskOffset = offset;
|
|
7782
|
+
directoryEndDiskEntriesLength = 0;
|
|
7656
7783
|
await writer.closeDisk();
|
|
7657
7784
|
}
|
|
7658
7785
|
if (indexFileEntry == 0) {
|
|
@@ -7688,6 +7815,7 @@
|
|
|
7688
7815
|
directoryRecord.writeBytes(rawComment);
|
|
7689
7816
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7690
7817
|
offset += directoryRecordLength;
|
|
7818
|
+
directoryEndDiskEntriesLength++;
|
|
7691
7819
|
if (options.onprogress) {
|
|
7692
7820
|
try {
|
|
7693
7821
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -7699,6 +7827,7 @@
|
|
|
7699
7827
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
7700
7828
|
return {
|
|
7701
7829
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
7830
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
7702
7831
|
directoryArray
|
|
7703
7832
|
};
|
|
7704
7833
|
}
|
|
@@ -7727,16 +7856,20 @@
|
|
|
7727
7856
|
|
|
7728
7857
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
7729
7858
|
const { writer } = zipWriter;
|
|
7730
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
7859
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
7731
7860
|
let { directoryDataLength } = cdInfo;
|
|
7732
7861
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7733
7862
|
let diskNumber = directoryStart.diskNumber;
|
|
7734
7863
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7864
|
+
const commentLength = getLength(comment);
|
|
7865
|
+
if (commentLength > MAX_16_BITS) {
|
|
7866
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
7867
|
+
}
|
|
7868
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7735
7869
|
let lastDiskNumber = getDiskNumber(writer);
|
|
7736
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
7870
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
7737
7871
|
lastDiskNumber++;
|
|
7738
7872
|
}
|
|
7739
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7740
7873
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7741
7874
|
if (zip64 === false) {
|
|
7742
7875
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -7744,15 +7877,12 @@
|
|
|
7744
7877
|
zip64 = true;
|
|
7745
7878
|
}
|
|
7746
7879
|
}
|
|
7747
|
-
const commentLength = getLength(comment);
|
|
7748
|
-
if (commentLength > MAX_16_BITS) {
|
|
7749
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
7750
|
-
}
|
|
7751
7880
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7752
7881
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
7753
7882
|
await writer.closeDisk();
|
|
7754
7883
|
}
|
|
7755
7884
|
lastDiskNumber = getDiskNumber(writer);
|
|
7885
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
7756
7886
|
if (zip64) {
|
|
7757
7887
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7758
7888
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -7760,7 +7890,7 @@
|
|
|
7760
7890
|
endOfdirectoryRecord.writeUint16(45);
|
|
7761
7891
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7762
7892
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7763
|
-
endOfdirectoryRecord.writeUint64(
|
|
7893
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
7764
7894
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7765
7895
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7766
7896
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -7773,6 +7903,7 @@
|
|
|
7773
7903
|
lastDiskNumber = MAX_16_BITS;
|
|
7774
7904
|
diskNumber = MAX_16_BITS;
|
|
7775
7905
|
}
|
|
7906
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
7776
7907
|
fileEntriesLength = MAX_16_BITS;
|
|
7777
7908
|
directoryOffset = MAX_32_BITS;
|
|
7778
7909
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -7780,7 +7911,7 @@
|
|
|
7780
7911
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7781
7912
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7782
7913
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7783
|
-
endOfdirectoryRecord.writeUint16(
|
|
7914
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
7784
7915
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7785
7916
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7786
7917
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -7830,6 +7961,21 @@
|
|
|
7830
7961
|
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7831
7962
|
}
|
|
7832
7963
|
|
|
7964
|
+
function removeExtraFieldZip64(rawExtraField) {
|
|
7965
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
7966
|
+
let offsetExtraField = 0;
|
|
7967
|
+
while (offsetExtraField + 4 <= getLength(rawExtraField)) {
|
|
7968
|
+
const size = 4 + getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
7969
|
+
if (getUint16(rawExtraFieldView, offsetExtraField) == EXTRAFIELD_TYPE_ZIP64) {
|
|
7970
|
+
return removeExtraFieldZip64(concat(
|
|
7971
|
+
rawExtraField.subarray(0, offsetExtraField),
|
|
7972
|
+
rawExtraField.subarray(Math.min(offsetExtraField + size, getLength(rawExtraField)))));
|
|
7973
|
+
}
|
|
7974
|
+
offsetExtraField += size;
|
|
7975
|
+
}
|
|
7976
|
+
return rawExtraField;
|
|
7977
|
+
}
|
|
7978
|
+
|
|
7833
7979
|
async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
7834
7980
|
const { writer } = zipWriter;
|
|
7835
7981
|
const entryPositions = new Map();
|
|
@@ -7864,9 +8010,21 @@
|
|
|
7864
8010
|
async function copyData(zipWriter, reader, offset, size) {
|
|
7865
8011
|
if (size > 0) {
|
|
7866
8012
|
const { writer } = zipWriter;
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
8013
|
+
let copiedLength = 0;
|
|
8014
|
+
try {
|
|
8015
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8016
|
+
} catch (error) {
|
|
8017
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8018
|
+
try {
|
|
8019
|
+
error.corruptedEntry = true;
|
|
8020
|
+
} catch {
|
|
8021
|
+
// ignored
|
|
8022
|
+
}
|
|
8023
|
+
throw error;
|
|
8024
|
+
} finally {
|
|
8025
|
+
writer.size += copiedLength;
|
|
8026
|
+
zipWriter.offset += copiedLength;
|
|
8027
|
+
}
|
|
7870
8028
|
}
|
|
7871
8029
|
}
|
|
7872
8030
|
|
|
@@ -7891,6 +8049,12 @@
|
|
|
7891
8049
|
return signatureArray;
|
|
7892
8050
|
}
|
|
7893
8051
|
|
|
8052
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
8053
|
+
delete zipWriter.addSplitZipSignature;
|
|
8054
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
8055
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
8056
|
+
}
|
|
8057
|
+
|
|
7894
8058
|
async function writeData(writer, array) {
|
|
7895
8059
|
const { writable } = writer;
|
|
7896
8060
|
const streamWriter = writable.getWriter();
|
|
@@ -8638,6 +8802,7 @@
|
|
|
8638
8802
|
exports.ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH;
|
|
8639
8803
|
exports.ERR_UNSUPPORTED_ENCRYPTION_USDZ = ERR_UNSUPPORTED_ENCRYPTION_USDZ;
|
|
8640
8804
|
exports.ERR_UNSUPPORTED_FORMAT = ERR_UNSUPPORTED_FORMAT;
|
|
8805
|
+
exports.ERR_UNSUPPORTED_UINT64 = ERR_UNSUPPORTED_UINT64;
|
|
8641
8806
|
exports.ERR_WORKER_STARTUP_TIMEOUT = ERR_WORKER_STARTUP_TIMEOUT;
|
|
8642
8807
|
exports.ERR_WRITER_NOT_INITIALIZED = ERR_WRITER_NOT_INITIALIZED;
|
|
8643
8808
|
exports.ERR_ZIP_NOT_EMPTY = ERR_ZIP_NOT_EMPTY;
|