@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-fs-core.js
CHANGED
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
const FILE_ATTR_UNIX_SETGID_MASK = 0o2000;
|
|
101
101
|
const FILE_ATTR_UNIX_STICKY_MASK = 0o1000;
|
|
102
102
|
|
|
103
|
+
const VERSION_STORE = 0x0A;
|
|
103
104
|
const VERSION_DEFLATE = 0x14;
|
|
104
105
|
const VERSION_ZIP64 = 0x2D;
|
|
105
106
|
const VERSION_AES = 0x33;
|
|
@@ -3608,6 +3609,8 @@
|
|
|
3608
3609
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
3609
3610
|
*/
|
|
3610
3611
|
|
|
3612
|
+
|
|
3613
|
+
const ERR_WORKER_STARTUP_TIMEOUT = "Worker startup timeout";
|
|
3611
3614
|
let initModule = () => { };
|
|
3612
3615
|
|
|
3613
3616
|
async function supportsDeflate(config) {
|
|
@@ -4122,6 +4125,7 @@
|
|
|
4122
4125
|
const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
|
|
4123
4126
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
4124
4127
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
4128
|
+
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
4125
4129
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4126
4130
|
const CHARSET_UTF8 = "utf-8";
|
|
4127
4131
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -4144,6 +4148,7 @@
|
|
|
4144
4148
|
bytes: 8
|
|
4145
4149
|
}
|
|
4146
4150
|
};
|
|
4151
|
+
const MAX_SAFE_UINT64 = BigInt(Number.MAX_SAFE_INTEGER);
|
|
4147
4152
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
4148
4153
|
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
4149
4154
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
@@ -4239,7 +4244,7 @@
|
|
|
4239
4244
|
zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
|
|
4240
4245
|
if (zip64EndOfDirectoryVersion2) {
|
|
4241
4246
|
const extensibleDataLength = Math.min(
|
|
4242
|
-
|
|
4247
|
+
getBigUint64(endOfDirectoryView, 4) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
|
|
4243
4248
|
reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4244
4249
|
if (extensibleDataLength > 0) {
|
|
4245
4250
|
zip64EndOfDirectoryLength += extensibleDataLength;
|
|
@@ -4339,6 +4344,10 @@
|
|
|
4339
4344
|
const commentEncoding = getOptionValue$1(zipReader, options, OPTION_COMMENT_ENCODING);
|
|
4340
4345
|
const filenames = checkAmbiguity ? new Set() : UNDEFINED_VALUE;
|
|
4341
4346
|
let duplicateFilename;
|
|
4347
|
+
const recoverWrappedFilesLength = !checkAmbiguity && !zip64EndOfDirectory;
|
|
4348
|
+
if (!filesLength && recoverWrappedFilesLength) {
|
|
4349
|
+
filesLength = getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4350
|
+
}
|
|
4342
4351
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4343
4352
|
const fileEntry = new ZipEntry$1(reader, zipReader.options);
|
|
4344
4353
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
@@ -4448,7 +4457,7 @@
|
|
|
4448
4457
|
internalFileAttribute: fileEntry.internalFileAttributes,
|
|
4449
4458
|
externalFileAttribute: fileEntry.externalFileAttributes,
|
|
4450
4459
|
executable,
|
|
4451
|
-
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) ||
|
|
4460
|
+
directory: modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE),
|
|
4452
4461
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
4453
4462
|
});
|
|
4454
4463
|
const entry = new Entry(fileEntry);
|
|
@@ -4461,6 +4470,9 @@
|
|
|
4461
4470
|
return arrayBufferPromise;
|
|
4462
4471
|
};
|
|
4463
4472
|
offset = endOffset;
|
|
4473
|
+
if (indexFile == filesLength - 1 && recoverWrappedFilesLength) {
|
|
4474
|
+
filesLength += getWrappedFilesLength(directoryView, directoryArray, offset);
|
|
4475
|
+
}
|
|
4464
4476
|
const { onprogress } = options;
|
|
4465
4477
|
if (onprogress) {
|
|
4466
4478
|
try {
|
|
@@ -4526,6 +4538,46 @@
|
|
|
4526
4538
|
}
|
|
4527
4539
|
}
|
|
4528
4540
|
|
|
4541
|
+
class ZipReaderStream {
|
|
4542
|
+
|
|
4543
|
+
constructor(options = {}) {
|
|
4544
|
+
const { readable, writable } = new TransformStream();
|
|
4545
|
+
const gen = new ZipReader(readable, options).getEntriesGenerator();
|
|
4546
|
+
this.readable = new ReadableStream({
|
|
4547
|
+
async pull(controller) {
|
|
4548
|
+
const { done, value } = await gen.next();
|
|
4549
|
+
if (done)
|
|
4550
|
+
return controller.close();
|
|
4551
|
+
const chunk = {
|
|
4552
|
+
...value,
|
|
4553
|
+
readable: (function () {
|
|
4554
|
+
const { readable, writable } = new TransformStream();
|
|
4555
|
+
if (value.getData) {
|
|
4556
|
+
getData();
|
|
4557
|
+
return readable;
|
|
4558
|
+
}
|
|
4559
|
+
|
|
4560
|
+
async function getData() {
|
|
4561
|
+
try {
|
|
4562
|
+
await value.getData(writable);
|
|
4563
|
+
} catch (error) {
|
|
4564
|
+
try {
|
|
4565
|
+
await writable.abort(error);
|
|
4566
|
+
} catch {
|
|
4567
|
+
// ignored
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
})()
|
|
4572
|
+
};
|
|
4573
|
+
delete chunk.getData;
|
|
4574
|
+
controller.enqueue(chunk);
|
|
4575
|
+
}
|
|
4576
|
+
});
|
|
4577
|
+
this.writable = writable;
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
|
|
4529
4581
|
let ZipEntry$1 = class ZipEntry {
|
|
4530
4582
|
|
|
4531
4583
|
constructor(reader, options) {
|
|
@@ -4579,6 +4631,7 @@
|
|
|
4579
4631
|
extraFieldLength,
|
|
4580
4632
|
filenameLength
|
|
4581
4633
|
} = localDirectory;
|
|
4634
|
+
const dataOffset = localDirectory.dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4582
4635
|
const checkLocalDirectoryOption = getOptionValue$1(zipEntry, options, OPTION_CHECK_LOCAL_DIRECTORY);
|
|
4583
4636
|
const entryStrictness = getStrictness(options, zipEntry.options);
|
|
4584
4637
|
const checkLocalDirectory = getCheckLocalDirectory(checkLocalDirectoryOption, entryStrictness);
|
|
@@ -4632,7 +4685,6 @@
|
|
|
4632
4685
|
throw new Error(ERR_ENCRYPTED);
|
|
4633
4686
|
}
|
|
4634
4687
|
}
|
|
4635
|
-
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4636
4688
|
if (dataOffset + compressedSize > reader.size) {
|
|
4637
4689
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
4638
4690
|
}
|
|
@@ -4752,6 +4804,16 @@
|
|
|
4752
4804
|
return false;
|
|
4753
4805
|
}
|
|
4754
4806
|
|
|
4807
|
+
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
4808
|
+
let wrappedFilesLength = 0;
|
|
4809
|
+
while (offset + CENTRAL_FILE_HEADER_LENGTH <= directoryArray.length && getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4810
|
+
offset += CENTRAL_FILE_HEADER_LENGTH +
|
|
4811
|
+
getUint16$1(directoryView, offset + 28) + getUint16$1(directoryView, offset + 30) + getUint16$1(directoryView, offset + 32);
|
|
4812
|
+
wrappedFilesLength++;
|
|
4813
|
+
}
|
|
4814
|
+
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
4815
|
+
}
|
|
4816
|
+
|
|
4755
4817
|
function readDigitalSignature(signatureRecordArray) {
|
|
4756
4818
|
if (signatureRecordArray.length >= 6) {
|
|
4757
4819
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -4780,8 +4842,8 @@
|
|
|
4780
4842
|
const hashDataLength = getUint16$1(extensibleDataView, 26);
|
|
4781
4843
|
Object.assign(directoryEncryptionInfo, {
|
|
4782
4844
|
compressionMethod: getUint16$1(extensibleDataView, 0),
|
|
4783
|
-
compressedSize:
|
|
4784
|
-
uncompressedSize:
|
|
4845
|
+
compressedSize: getBigUint64(extensibleDataView, 2),
|
|
4846
|
+
uncompressedSize: getBigUint64(extensibleDataView, 10),
|
|
4785
4847
|
encryptionAlgorithm: getUint16$1(extensibleDataView, 18),
|
|
4786
4848
|
bitLength: getUint16$1(extensibleDataView, 20),
|
|
4787
4849
|
flags: getUint16$1(extensibleDataView, 22),
|
|
@@ -4924,10 +4986,11 @@
|
|
|
4924
4986
|
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
4925
4987
|
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
4926
4988
|
const nameCrc32 = getUint32$1(extraFieldView, 1);
|
|
4989
|
+
const version = getUint8(extraFieldView, 0);
|
|
4927
4990
|
Object.assign(extraFieldUnicode, {
|
|
4928
|
-
version
|
|
4991
|
+
version,
|
|
4929
4992
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
4930
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
4993
|
+
valid: version == 1 && !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32$1(computedCrc32View, 0)
|
|
4931
4994
|
});
|
|
4932
4995
|
if (extraFieldUnicode.valid) {
|
|
4933
4996
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5396,7 +5459,8 @@
|
|
|
5396
5459
|
|
|
5397
5460
|
function getDate(timeRaw) {
|
|
5398
5461
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5399
|
-
|
|
5462
|
+
const result = new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
5463
|
+
return result < MIN_DATE ? MIN_DATE : result;
|
|
5400
5464
|
}
|
|
5401
5465
|
|
|
5402
5466
|
function getDateNTFS(timeRaw) {
|
|
@@ -5416,7 +5480,11 @@
|
|
|
5416
5480
|
}
|
|
5417
5481
|
|
|
5418
5482
|
function getBigUint64(view, offset) {
|
|
5419
|
-
|
|
5483
|
+
const value = view.getBigUint64(offset, true);
|
|
5484
|
+
if (value > MAX_SAFE_UINT64) {
|
|
5485
|
+
throw new Error(ERR_UNSUPPORTED_UINT64);
|
|
5486
|
+
}
|
|
5487
|
+
return Number(value);
|
|
5420
5488
|
}
|
|
5421
5489
|
|
|
5422
5490
|
var zipReader = /*#__PURE__*/Object.freeze({
|
|
@@ -5445,7 +5513,10 @@
|
|
|
5445
5513
|
ERR_UNSAFE_FILENAME: ERR_UNSAFE_FILENAME,
|
|
5446
5514
|
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
5447
5515
|
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
5448
|
-
|
|
5516
|
+
ERR_UNSUPPORTED_UINT64: ERR_UNSUPPORTED_UINT64,
|
|
5517
|
+
ERR_WORKER_STARTUP_TIMEOUT: ERR_WORKER_STARTUP_TIMEOUT,
|
|
5518
|
+
ZipReader: ZipReader,
|
|
5519
|
+
ZipReaderStream: ZipReaderStream
|
|
5449
5520
|
});
|
|
5450
5521
|
|
|
5451
5522
|
/*
|
|
@@ -5542,153 +5613,150 @@
|
|
|
5542
5613
|
offset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? writer.size || writer.writable.size || 0 : options[OPTION_OFFSET],
|
|
5543
5614
|
initialOffset: options[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : options[OPTION_OFFSET] - (writer.size || writer.writable.size || 0),
|
|
5544
5615
|
pendingAddFileCalls: new Set(),
|
|
5616
|
+
pendingErrors: [],
|
|
5545
5617
|
bufferedWrites: 0,
|
|
5546
5618
|
lastFileEntry: UNDEFINED_VALUE
|
|
5547
5619
|
});
|
|
5548
5620
|
}
|
|
5549
5621
|
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5557
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5558
|
-
await initStream(reader);
|
|
5559
|
-
}
|
|
5560
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5561
|
-
const zipReader$1 = new ZipReader(reader);
|
|
5562
|
-
const entries = await zipReader$1.getEntries();
|
|
5563
|
-
await zipReader$1.close();
|
|
5564
|
-
await initStream(this.writer);
|
|
5565
|
-
const { directoryOffset } = zipReader$1;
|
|
5566
|
-
if (this.addSplitZipSignature) {
|
|
5567
|
-
delete this.addSplitZipSignature;
|
|
5568
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
5569
|
-
await writeData(this.writer, getSplitZipSignatureArray());
|
|
5570
|
-
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
5571
|
-
}
|
|
5572
|
-
}
|
|
5573
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
5574
|
-
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
5575
|
-
this.fileEntries = new Map(entries.map(entry => {
|
|
5576
|
-
const {
|
|
5577
|
-
version,
|
|
5578
|
-
rawLastModDate,
|
|
5579
|
-
lastAccessDate,
|
|
5580
|
-
creationDate,
|
|
5581
|
-
rawFilename,
|
|
5582
|
-
bitFlag,
|
|
5583
|
-
encrypted,
|
|
5584
|
-
uncompressedSize,
|
|
5585
|
-
compressedSize,
|
|
5586
|
-
zip64
|
|
5587
|
-
} = entry;
|
|
5588
|
-
let {
|
|
5589
|
-
compressionMethod,
|
|
5590
|
-
rawExtraFieldZip64,
|
|
5591
|
-
rawExtraFieldAES,
|
|
5592
|
-
rawExtraFieldExtendedTimestamp,
|
|
5593
|
-
rawExtraFieldNTFS,
|
|
5594
|
-
rawExtraFieldUnix,
|
|
5595
|
-
rawExtraField,
|
|
5596
|
-
} = entry;
|
|
5597
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
5598
|
-
rawExtraFieldZip64 = rawExtraFieldZip64 || EMPTY_UINT8_ARRAY;
|
|
5599
|
-
rawExtraFieldAES = rawExtraFieldAES || EMPTY_UINT8_ARRAY;
|
|
5600
|
-
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
5601
|
-
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
5602
|
-
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
5603
|
-
rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
|
|
5604
|
-
if (entry.extraFieldAES) {
|
|
5605
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
5606
|
-
}
|
|
5607
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
5608
|
-
const zip64UncompressedSize = zip64 && uncompressedSize >= MAX_32_BITS;
|
|
5609
|
-
const zip64CompressedSize = zip64 && compressedSize >= MAX_32_BITS;
|
|
5610
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
5611
|
-
const {
|
|
5612
|
-
headerArray,
|
|
5613
|
-
headerView
|
|
5614
|
-
} = getHeaderArrayData({
|
|
5615
|
-
version,
|
|
5616
|
-
bitFlag: bitFlagValue,
|
|
5617
|
-
compressionMethod,
|
|
5618
|
-
uncompressedSize,
|
|
5619
|
-
compressedSize,
|
|
5620
|
-
rawLastModDate,
|
|
5621
|
-
rawFilename,
|
|
5622
|
-
zip64CompressedSize,
|
|
5623
|
-
zip64UncompressedSize,
|
|
5624
|
-
extraFieldLength
|
|
5625
|
-
});
|
|
5626
|
-
const { crc32 } = entry;
|
|
5627
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
5628
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5629
|
-
}
|
|
5630
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5631
|
-
Object.assign(entry, {
|
|
5632
|
-
zip64UncompressedSize,
|
|
5633
|
-
zip64CompressedSize,
|
|
5634
|
-
offset,
|
|
5635
|
-
diskNumberStart,
|
|
5636
|
-
zip64DiskNumberStart: false,
|
|
5637
|
-
rawExtraFieldZip64,
|
|
5638
|
-
rawExtraFieldAES,
|
|
5639
|
-
rawExtraFieldExtendedTimestamp,
|
|
5640
|
-
rawExtraFieldNTFS,
|
|
5641
|
-
rawExtraFieldUnix,
|
|
5642
|
-
rawExtraField,
|
|
5643
|
-
extendedTimestamp: rawExtraFieldExtendedTimestamp.length > 0 || rawExtraFieldNTFS.length > 0,
|
|
5644
|
-
extraFieldExtendedTimestampFlag: 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0),
|
|
5645
|
-
headerArray,
|
|
5646
|
-
headerView
|
|
5647
|
-
});
|
|
5648
|
-
return [entry.filename, entry];
|
|
5649
|
-
}));
|
|
5622
|
+
prependZip(reader) {
|
|
5623
|
+
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
5624
|
+
}
|
|
5625
|
+
|
|
5626
|
+
appendZip(reader) {
|
|
5627
|
+
return watchPromiseError(this, this.appendZipEntries(reader));
|
|
5650
5628
|
}
|
|
5651
5629
|
|
|
5652
|
-
async
|
|
5630
|
+
async appendZipEntries(reader) {
|
|
5653
5631
|
const zipWriter = this;
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
workers++;
|
|
5658
|
-
} else {
|
|
5659
|
-
await new Promise(resolve => pendingEntries.push(resolve));
|
|
5632
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
5633
|
+
while (pendingAddFileCalls.size) {
|
|
5634
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5660
5635
|
}
|
|
5661
|
-
let
|
|
5662
|
-
|
|
5636
|
+
let resolveAppendZip;
|
|
5637
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
5638
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
5639
|
+
const appendedFilenames = [];
|
|
5640
|
+
let releaseLockWriter;
|
|
5663
5641
|
try {
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
}
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5642
|
+
reader = new GenericReader(reader);
|
|
5643
|
+
await initStream(reader);
|
|
5644
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
5645
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
5646
|
+
await initStream(reader);
|
|
5647
|
+
}
|
|
5648
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5649
|
+
const zipReader$1 = new ZipReader(reader);
|
|
5650
|
+
const entries = await zipReader$1.getEntries();
|
|
5651
|
+
await zipReader$1.close();
|
|
5652
|
+
await initStream(zipWriter.writer);
|
|
5653
|
+
const { directoryOffset } = zipReader$1;
|
|
5654
|
+
entries.forEach(({ filename }) => {
|
|
5655
|
+
if (filenames.has(filename)) {
|
|
5656
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
5657
|
+
}
|
|
5658
|
+
filenames.add(filename);
|
|
5659
|
+
appendedFilenames.push(filename);
|
|
5660
|
+
});
|
|
5661
|
+
zipWriter.writerLocked = true;
|
|
5662
|
+
const { lockWriter } = zipWriter;
|
|
5663
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
5664
|
+
zipWriter.writerLocked = false;
|
|
5665
|
+
resolve();
|
|
5666
|
+
});
|
|
5667
|
+
await lockWriter;
|
|
5668
|
+
if (zipWriter.addSplitZipSignature) {
|
|
5669
|
+
delete zipWriter.addSplitZipSignature;
|
|
5670
|
+
if (!await startsWithSplitZipSignature(reader)) {
|
|
5671
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
5672
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
5673
|
+
}
|
|
5679
5674
|
}
|
|
5675
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
5676
|
+
entries.forEach(entry => {
|
|
5677
|
+
const {
|
|
5678
|
+
version,
|
|
5679
|
+
rawLastModDate,
|
|
5680
|
+
rawFilename,
|
|
5681
|
+
bitFlag,
|
|
5682
|
+
encrypted,
|
|
5683
|
+
uncompressedSize,
|
|
5684
|
+
compressedSize,
|
|
5685
|
+
extraFieldZip64
|
|
5686
|
+
} = entry;
|
|
5687
|
+
let {
|
|
5688
|
+
compressionMethod,
|
|
5689
|
+
rawExtraField,
|
|
5690
|
+
} = entry;
|
|
5691
|
+
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
5692
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
5693
|
+
if (entry.extraFieldAES) {
|
|
5694
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
5695
|
+
}
|
|
5696
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
5697
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
5698
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
5699
|
+
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
5700
|
+
const {
|
|
5701
|
+
headerArray,
|
|
5702
|
+
headerView
|
|
5703
|
+
} = getHeaderArrayData({
|
|
5704
|
+
version,
|
|
5705
|
+
bitFlag: bitFlagValue,
|
|
5706
|
+
compressionMethod,
|
|
5707
|
+
uncompressedSize,
|
|
5708
|
+
compressedSize,
|
|
5709
|
+
rawLastModDate,
|
|
5710
|
+
rawFilename,
|
|
5711
|
+
zip64CompressedSize,
|
|
5712
|
+
zip64UncompressedSize,
|
|
5713
|
+
extraFieldLength
|
|
5714
|
+
});
|
|
5715
|
+
const { crc32 } = entry;
|
|
5716
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
5717
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5718
|
+
}
|
|
5719
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
5720
|
+
Object.assign(entry, {
|
|
5721
|
+
zip64UncompressedSize,
|
|
5722
|
+
zip64CompressedSize,
|
|
5723
|
+
offset,
|
|
5724
|
+
diskNumberStart,
|
|
5725
|
+
zip64DiskNumberStart: false,
|
|
5726
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
5727
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
5728
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
5729
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
5730
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
5731
|
+
rawExtraField,
|
|
5732
|
+
extendedTimestamp: false,
|
|
5733
|
+
headerArray,
|
|
5734
|
+
headerView
|
|
5735
|
+
});
|
|
5736
|
+
fileEntries.set(entry.filename, entry);
|
|
5737
|
+
});
|
|
5738
|
+
} catch (error) {
|
|
5739
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
5680
5740
|
throw error;
|
|
5681
5741
|
} finally {
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
if (
|
|
5685
|
-
|
|
5686
|
-
} else {
|
|
5687
|
-
workers--;
|
|
5742
|
+
resolveAppendZip();
|
|
5743
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
5744
|
+
if (releaseLockWriter) {
|
|
5745
|
+
releaseLockWriter();
|
|
5688
5746
|
}
|
|
5689
5747
|
}
|
|
5690
5748
|
}
|
|
5691
5749
|
|
|
5750
|
+
add(name = "", reader, options = {}) {
|
|
5751
|
+
const zipWriter = this;
|
|
5752
|
+
const { pendingAddFileCalls } = zipWriter;
|
|
5753
|
+
const promiseAddFile = addFileEntry(zipWriter, name, reader, options);
|
|
5754
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
5755
|
+
const deletePendingAddFileCall = () => pendingAddFileCalls.delete(promiseAddFile);
|
|
5756
|
+
Promise.prototype.then.call(promiseAddFile, deletePendingAddFileCall, deletePendingAddFileCall);
|
|
5757
|
+
return watchPromiseError(zipWriter, promiseAddFile);
|
|
5758
|
+
}
|
|
5759
|
+
|
|
5692
5760
|
remove(entry) {
|
|
5693
5761
|
const { filenames, fileEntries } = this;
|
|
5694
5762
|
// deno-lint-ignore valid-typeof
|
|
@@ -5719,6 +5787,19 @@
|
|
|
5719
5787
|
while (pendingAddFileCalls.size) {
|
|
5720
5788
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
5721
5789
|
}
|
|
5790
|
+
await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
|
|
5791
|
+
const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
|
|
5792
|
+
if (unobservedWatchers.length) {
|
|
5793
|
+
const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
|
|
5794
|
+
unobservedWatchers.forEach(watcher => watcher.observed = true);
|
|
5795
|
+
const [error] = unobservedErrors;
|
|
5796
|
+
try {
|
|
5797
|
+
error.entryErrors = unobservedErrors;
|
|
5798
|
+
} catch {
|
|
5799
|
+
// ignored
|
|
5800
|
+
}
|
|
5801
|
+
throw error;
|
|
5802
|
+
}
|
|
5722
5803
|
await closeFile(zipWriter, comment, options);
|
|
5723
5804
|
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
5724
5805
|
if (!preventClose) {
|
|
@@ -5728,6 +5809,63 @@
|
|
|
5728
5809
|
}
|
|
5729
5810
|
}
|
|
5730
5811
|
|
|
5812
|
+
class WatchedPromise extends Promise {
|
|
5813
|
+
|
|
5814
|
+
then(onFulfilled, onRejected) {
|
|
5815
|
+
const { watcher } = this;
|
|
5816
|
+
if (watcher) {
|
|
5817
|
+
watcher.observed = true;
|
|
5818
|
+
}
|
|
5819
|
+
return super.then(onFulfilled, onRejected);
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5823
|
+
function watchPromiseError(zipWriter, promise) {
|
|
5824
|
+
const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
|
|
5825
|
+
const watcher = {};
|
|
5826
|
+
watchedPromise.watcher = watcher;
|
|
5827
|
+
watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
|
|
5828
|
+
zipWriter.pendingErrors.push(watcher);
|
|
5829
|
+
return watchedPromise;
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
async function prependZipEntries(zipWriter, reader) {
|
|
5833
|
+
if (zipWriter.filenames.size) {
|
|
5834
|
+
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
5835
|
+
}
|
|
5836
|
+
await zipWriter.appendZipEntries(reader);
|
|
5837
|
+
}
|
|
5838
|
+
|
|
5839
|
+
async function addFileEntry(zipWriter, name, reader, options) {
|
|
5840
|
+
options = Object.assign({}, options);
|
|
5841
|
+
name = name.trim();
|
|
5842
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
5843
|
+
name += DIRECTORY_SIGNATURE;
|
|
5844
|
+
}
|
|
5845
|
+
if (zipWriter.filenames.has(name)) {
|
|
5846
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
5847
|
+
}
|
|
5848
|
+
zipWriter.filenames.add(name);
|
|
5849
|
+
if (workers < getConfiguration().maxWorkers) {
|
|
5850
|
+
workers++;
|
|
5851
|
+
} else {
|
|
5852
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
5853
|
+
}
|
|
5854
|
+
try {
|
|
5855
|
+
return await addFile(zipWriter, name, reader, options);
|
|
5856
|
+
} catch (error) {
|
|
5857
|
+
zipWriter.filenames.delete(name);
|
|
5858
|
+
throw error;
|
|
5859
|
+
} finally {
|
|
5860
|
+
const pendingEntry = pendingEntries.shift();
|
|
5861
|
+
if (pendingEntry) {
|
|
5862
|
+
pendingEntry();
|
|
5863
|
+
} else {
|
|
5864
|
+
workers--;
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
|
|
5731
5869
|
async function addFile(zipWriter, name, reader, options) {
|
|
5732
5870
|
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
5733
5871
|
({ name } = attributesInfo);
|
|
@@ -5916,11 +6054,12 @@
|
|
|
5916
6054
|
if (getLength(rawComment) > MAX_16_BITS) {
|
|
5917
6055
|
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
5918
6056
|
}
|
|
5919
|
-
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION
|
|
5920
|
-
if (version > MAX_16_BITS) {
|
|
6057
|
+
const version = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION);
|
|
6058
|
+
if (version !== UNDEFINED_VALUE && version > MAX_16_BITS) {
|
|
5921
6059
|
throw new Error(ERR_INVALID_VERSION);
|
|
5922
6060
|
}
|
|
5923
6061
|
const lastModDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
6062
|
+
const rawLastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_RAW_LAST_MODIFICATION_DATE);
|
|
5924
6063
|
const lastAccessDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
5925
6064
|
const creationDate = getDateOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
5926
6065
|
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
@@ -5964,7 +6103,7 @@
|
|
|
5964
6103
|
if (bufferedWrite && dataDescriptor === UNDEFINED_VALUE) {
|
|
5965
6104
|
dataDescriptor = false;
|
|
5966
6105
|
}
|
|
5967
|
-
if (dataDescriptor === UNDEFINED_VALUE || zipCrypto) {
|
|
6106
|
+
if (dataDescriptor === UNDEFINED_VALUE || (zipCrypto && !passThrough)) {
|
|
5968
6107
|
dataDescriptor = true;
|
|
5969
6108
|
}
|
|
5970
6109
|
if (level !== UNDEFINED_VALUE && level != 6) {
|
|
@@ -5983,6 +6122,7 @@
|
|
|
5983
6122
|
rawComment,
|
|
5984
6123
|
version,
|
|
5985
6124
|
lastModDate,
|
|
6125
|
+
rawLastModDate,
|
|
5986
6126
|
lastAccessDate,
|
|
5987
6127
|
creationDate,
|
|
5988
6128
|
internalFileAttributes,
|
|
@@ -6100,6 +6240,10 @@
|
|
|
6100
6240
|
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
6101
6241
|
}
|
|
6102
6242
|
}
|
|
6243
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
|
|
6244
|
+
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
6245
|
+
dataDescriptor = false;
|
|
6246
|
+
}
|
|
6103
6247
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
6104
6248
|
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
6105
6249
|
if (zip64UncompressedSize || zip64CompressedSize) {
|
|
@@ -6114,6 +6258,7 @@
|
|
|
6114
6258
|
maximumCompressedSize,
|
|
6115
6259
|
resolvedOptions: {
|
|
6116
6260
|
dataDescriptor,
|
|
6261
|
+
emptyEntry,
|
|
6117
6262
|
zip64,
|
|
6118
6263
|
zip64UncompressedSize,
|
|
6119
6264
|
zip64CompressedSize,
|
|
@@ -6212,6 +6357,7 @@
|
|
|
6212
6357
|
const {
|
|
6213
6358
|
keepOrder,
|
|
6214
6359
|
dataDescriptor,
|
|
6360
|
+
emptyEntry,
|
|
6215
6361
|
signal
|
|
6216
6362
|
} = options;
|
|
6217
6363
|
const {
|
|
@@ -6236,7 +6382,7 @@
|
|
|
6236
6382
|
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
6237
6383
|
requestLockCurrentFileEntry();
|
|
6238
6384
|
}
|
|
6239
|
-
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
6385
|
+
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
|
|
6240
6386
|
bufferedWrite = true;
|
|
6241
6387
|
zipWriter.bufferedWrites++;
|
|
6242
6388
|
if (options.createTempStream) {
|
|
@@ -6252,10 +6398,8 @@
|
|
|
6252
6398
|
}
|
|
6253
6399
|
await initStream(fileWriter);
|
|
6254
6400
|
const diskOffset = getDiskOffset(writer);
|
|
6255
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6256
|
-
|
|
6257
|
-
await writeData(writer, getSplitZipSignatureArray());
|
|
6258
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6401
|
+
if (zipWriter.addSplitZipSignature && !bufferedWrite) {
|
|
6402
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6259
6403
|
}
|
|
6260
6404
|
if (usdz && !bufferedWrite) {
|
|
6261
6405
|
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
@@ -6282,6 +6426,9 @@
|
|
|
6282
6426
|
if (bufferedWrite) {
|
|
6283
6427
|
await Promise.all([fileWriter.writable.getWriter().close(), lockPreviousFileEntry]);
|
|
6284
6428
|
await requestLockWriter();
|
|
6429
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6430
|
+
await writeSplitZipSignature(zipWriter, writer);
|
|
6431
|
+
}
|
|
6285
6432
|
writingBufferedEntryData = true;
|
|
6286
6433
|
writerSizeBeforeEntry = writer.size;
|
|
6287
6434
|
await skipDiskIfNeeded();
|
|
@@ -6553,6 +6700,7 @@
|
|
|
6553
6700
|
const {
|
|
6554
6701
|
rawFilename,
|
|
6555
6702
|
lastModDate,
|
|
6703
|
+
rawLastModDate: rawLastModDateOption,
|
|
6556
6704
|
lastAccessDate,
|
|
6557
6705
|
creationDate,
|
|
6558
6706
|
level,
|
|
@@ -6658,8 +6806,8 @@
|
|
|
6658
6806
|
try {
|
|
6659
6807
|
const { uid, gid, unixExtraFieldType } = options;
|
|
6660
6808
|
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE$1 && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
6661
|
-
const uidBytes = packUnixId(uid);
|
|
6662
|
-
const gidBytes = packUnixId(gid);
|
|
6809
|
+
const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
|
|
6810
|
+
const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
|
|
6663
6811
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
6664
6812
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
6665
6813
|
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
@@ -6686,6 +6834,9 @@
|
|
|
6686
6834
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
6687
6835
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
6688
6836
|
}
|
|
6837
|
+
if (version === UNDEFINED_VALUE) {
|
|
6838
|
+
version = compressionMethod == COMPRESSION_METHOD_STORE && !directory && !encrypted ? VERSION_STORE : VERSION_DEFLATE;
|
|
6839
|
+
}
|
|
6689
6840
|
const { codecVersionNeeded } = options;
|
|
6690
6841
|
if (compressed && codecVersionNeeded !== UNDEFINED_VALUE) {
|
|
6691
6842
|
version = version > codecVersionNeeded ? version : codecVersionNeeded;
|
|
@@ -6718,6 +6869,7 @@
|
|
|
6718
6869
|
compressionMethod,
|
|
6719
6870
|
uncompressedSize,
|
|
6720
6871
|
lastModDate: dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate,
|
|
6872
|
+
rawLastModDate: rawLastModDateOption,
|
|
6721
6873
|
rawFilename,
|
|
6722
6874
|
zip64CompressedSize,
|
|
6723
6875
|
zip64UncompressedSize,
|
|
@@ -6790,18 +6942,14 @@
|
|
|
6790
6942
|
}
|
|
6791
6943
|
|
|
6792
6944
|
function packUnixId(id) {
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
let length = 4;
|
|
6800
|
-
while (length > 1 && dataArray[length - 1] === 0) {
|
|
6801
|
-
length--;
|
|
6802
|
-
}
|
|
6803
|
-
return dataArray.subarray(0, length);
|
|
6945
|
+
const dataArray = new Uint8Array(4);
|
|
6946
|
+
const dataView = getDataView(dataArray);
|
|
6947
|
+
dataView.setUint32(0, id, true);
|
|
6948
|
+
let length = 4;
|
|
6949
|
+
while (length > 1 && dataArray[length - 1] === 0) {
|
|
6950
|
+
length--;
|
|
6804
6951
|
}
|
|
6952
|
+
return dataArray.subarray(0, length);
|
|
6805
6953
|
}
|
|
6806
6954
|
|
|
6807
6955
|
function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
|
|
@@ -6928,9 +7076,9 @@
|
|
|
6928
7076
|
|
|
6929
7077
|
async function closeFile(zipWriter, comment, options) {
|
|
6930
7078
|
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
6931
|
-
const { directoryStart, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
7079
|
+
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6932
7080
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
6933
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength, signatureLength });
|
|
7081
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
6934
7082
|
}
|
|
6935
7083
|
|
|
6936
7084
|
function createDirectoryRecords(files) {
|
|
@@ -7014,6 +7162,7 @@
|
|
|
7014
7162
|
let directoryDiskOffset = 0;
|
|
7015
7163
|
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
7016
7164
|
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
7165
|
+
let directoryEndDiskEntriesLength = 0;
|
|
7017
7166
|
for (const [indexFileEntry, fileEntry] of Array.from(fileEntries.values()).entries()) {
|
|
7018
7167
|
const {
|
|
7019
7168
|
offset: fileEntryOffset,
|
|
@@ -7043,6 +7192,7 @@
|
|
|
7043
7192
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
7044
7193
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
7045
7194
|
directoryDiskOffset = offset;
|
|
7195
|
+
directoryEndDiskEntriesLength = 0;
|
|
7046
7196
|
await writer.closeDisk();
|
|
7047
7197
|
}
|
|
7048
7198
|
if (indexFileEntry == 0) {
|
|
@@ -7078,6 +7228,7 @@
|
|
|
7078
7228
|
directoryRecord.writeBytes(rawComment);
|
|
7079
7229
|
arraySet(directoryArray, directoryRecord.array, offset);
|
|
7080
7230
|
offset += directoryRecordLength;
|
|
7231
|
+
directoryEndDiskEntriesLength++;
|
|
7081
7232
|
if (options.onprogress) {
|
|
7082
7233
|
try {
|
|
7083
7234
|
await options.onprogress(indexFileEntry + 1, fileEntries.size, new Entry(fileEntry));
|
|
@@ -7089,6 +7240,7 @@
|
|
|
7089
7240
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
7090
7241
|
return {
|
|
7091
7242
|
directoryStart: { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset },
|
|
7243
|
+
directoryEnd: { diskNumber: getDiskNumber(writer), entriesLength: directoryEndDiskEntriesLength },
|
|
7092
7244
|
directoryArray
|
|
7093
7245
|
};
|
|
7094
7246
|
}
|
|
@@ -7117,16 +7269,20 @@
|
|
|
7117
7269
|
|
|
7118
7270
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
7119
7271
|
const { writer } = zipWriter;
|
|
7120
|
-
const { directoryStart, signatureLength } = cdInfo;
|
|
7272
|
+
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
7121
7273
|
let { directoryDataLength } = cdInfo;
|
|
7122
7274
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
7123
7275
|
let diskNumber = directoryStart.diskNumber;
|
|
7124
7276
|
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
7277
|
+
const commentLength = getLength(comment);
|
|
7278
|
+
if (commentLength > MAX_16_BITS) {
|
|
7279
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
7280
|
+
}
|
|
7281
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7125
7282
|
let lastDiskNumber = getDiskNumber(writer);
|
|
7126
|
-
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
7283
|
+
if (exceedsAvailableSize(writer, (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH) + commentLength)) {
|
|
7127
7284
|
lastDiskNumber++;
|
|
7128
7285
|
}
|
|
7129
|
-
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
7130
7286
|
if (directoryOffset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || fileEntriesLength >= MAX_16_BITS || lastDiskNumber >= MAX_16_BITS) {
|
|
7131
7287
|
if (zip64 === false) {
|
|
7132
7288
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
@@ -7134,15 +7290,12 @@
|
|
|
7134
7290
|
zip64 = true;
|
|
7135
7291
|
}
|
|
7136
7292
|
}
|
|
7137
|
-
const commentLength = getLength(comment);
|
|
7138
|
-
if (commentLength > MAX_16_BITS) {
|
|
7139
|
-
throw new Error(ERR_INVALID_COMMENT);
|
|
7140
|
-
}
|
|
7141
7293
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
7142
7294
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
7143
7295
|
await writer.closeDisk();
|
|
7144
7296
|
}
|
|
7145
7297
|
lastDiskNumber = getDiskNumber(writer);
|
|
7298
|
+
let diskFileEntriesLength = lastDiskNumber == directoryEnd.diskNumber ? directoryEnd.entriesLength : 0;
|
|
7146
7299
|
if (zip64) {
|
|
7147
7300
|
endOfdirectoryRecord.writeUint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7148
7301
|
endOfdirectoryRecord.writeUint64(44);
|
|
@@ -7150,7 +7303,7 @@
|
|
|
7150
7303
|
endOfdirectoryRecord.writeUint16(45);
|
|
7151
7304
|
endOfdirectoryRecord.writeUint32(lastDiskNumber);
|
|
7152
7305
|
endOfdirectoryRecord.writeUint32(diskNumber);
|
|
7153
|
-
endOfdirectoryRecord.writeUint64(
|
|
7306
|
+
endOfdirectoryRecord.writeUint64(diskFileEntriesLength);
|
|
7154
7307
|
endOfdirectoryRecord.writeUint64(fileEntriesLength);
|
|
7155
7308
|
endOfdirectoryRecord.writeUint64(directoryDataLength);
|
|
7156
7309
|
endOfdirectoryRecord.writeUint64(directoryOffset);
|
|
@@ -7163,6 +7316,7 @@
|
|
|
7163
7316
|
lastDiskNumber = MAX_16_BITS;
|
|
7164
7317
|
diskNumber = MAX_16_BITS;
|
|
7165
7318
|
}
|
|
7319
|
+
diskFileEntriesLength = MAX_16_BITS;
|
|
7166
7320
|
fileEntriesLength = MAX_16_BITS;
|
|
7167
7321
|
directoryOffset = MAX_32_BITS;
|
|
7168
7322
|
directoryDataLength = MAX_32_BITS;
|
|
@@ -7170,7 +7324,7 @@
|
|
|
7170
7324
|
endOfdirectoryRecord.writeUint32(END_OF_CENTRAL_DIR_SIGNATURE);
|
|
7171
7325
|
endOfdirectoryRecord.writeUint16(lastDiskNumber);
|
|
7172
7326
|
endOfdirectoryRecord.writeUint16(diskNumber);
|
|
7173
|
-
endOfdirectoryRecord.writeUint16(
|
|
7327
|
+
endOfdirectoryRecord.writeUint16(diskFileEntriesLength);
|
|
7174
7328
|
endOfdirectoryRecord.writeUint16(fileEntriesLength);
|
|
7175
7329
|
endOfdirectoryRecord.writeUint32(directoryDataLength);
|
|
7176
7330
|
endOfdirectoryRecord.writeUint32(directoryOffset);
|
|
@@ -7220,6 +7374,21 @@
|
|
|
7220
7374
|
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
7221
7375
|
}
|
|
7222
7376
|
|
|
7377
|
+
function removeExtraFieldZip64(rawExtraField) {
|
|
7378
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
7379
|
+
let offsetExtraField = 0;
|
|
7380
|
+
while (offsetExtraField + 4 <= getLength(rawExtraField)) {
|
|
7381
|
+
const size = 4 + getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
7382
|
+
if (getUint16(rawExtraFieldView, offsetExtraField) == EXTRAFIELD_TYPE_ZIP64) {
|
|
7383
|
+
return removeExtraFieldZip64(concat(
|
|
7384
|
+
rawExtraField.subarray(0, offsetExtraField),
|
|
7385
|
+
rawExtraField.subarray(Math.min(offsetExtraField + size, getLength(rawExtraField)))));
|
|
7386
|
+
}
|
|
7387
|
+
offsetExtraField += size;
|
|
7388
|
+
}
|
|
7389
|
+
return rawExtraField;
|
|
7390
|
+
}
|
|
7391
|
+
|
|
7223
7392
|
async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
7224
7393
|
const { writer } = zipWriter;
|
|
7225
7394
|
const entryPositions = new Map();
|
|
@@ -7254,9 +7423,21 @@
|
|
|
7254
7423
|
async function copyData(zipWriter, reader, offset, size) {
|
|
7255
7424
|
if (size > 0) {
|
|
7256
7425
|
const { writer } = zipWriter;
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7426
|
+
let copiedLength = 0;
|
|
7427
|
+
try {
|
|
7428
|
+
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
7429
|
+
} catch (error) {
|
|
7430
|
+
zipWriter.hasCorruptedEntries = true;
|
|
7431
|
+
try {
|
|
7432
|
+
error.corruptedEntry = true;
|
|
7433
|
+
} catch {
|
|
7434
|
+
// ignored
|
|
7435
|
+
}
|
|
7436
|
+
throw error;
|
|
7437
|
+
} finally {
|
|
7438
|
+
writer.size += copiedLength;
|
|
7439
|
+
zipWriter.offset += copiedLength;
|
|
7440
|
+
}
|
|
7260
7441
|
}
|
|
7261
7442
|
}
|
|
7262
7443
|
|
|
@@ -7281,6 +7462,12 @@
|
|
|
7281
7462
|
return signatureArray;
|
|
7282
7463
|
}
|
|
7283
7464
|
|
|
7465
|
+
async function writeSplitZipSignature(zipWriter, writer) {
|
|
7466
|
+
delete zipWriter.addSplitZipSignature;
|
|
7467
|
+
await writeData(writer, getSplitZipSignatureArray());
|
|
7468
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
7469
|
+
}
|
|
7470
|
+
|
|
7284
7471
|
async function writeData(writer, array) {
|
|
7285
7472
|
const { writable } = writer;
|
|
7286
7473
|
const streamWriter = writable.getWriter();
|
|
@@ -7512,6 +7699,7 @@
|
|
|
7512
7699
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
7513
7700
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
7514
7701
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
7702
|
+
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
7515
7703
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
7516
7704
|
const ERR_ABORTED = "The operation was aborted";
|
|
7517
7705
|
const ABORT_ERROR_NAME = "AbortError";
|
|
@@ -8269,7 +8457,7 @@
|
|
|
8269
8457
|
} else if (writer.constructor == BlobWriter) {
|
|
8270
8458
|
return data.type == contentType;
|
|
8271
8459
|
} else if (writer.constructor == Data64URIWriter) {
|
|
8272
|
-
return data.startsWith(
|
|
8460
|
+
return data.startsWith("data:" + (contentType || "") + ";base64,");
|
|
8273
8461
|
} else {
|
|
8274
8462
|
return true;
|
|
8275
8463
|
}
|
|
@@ -8379,6 +8567,7 @@
|
|
|
8379
8567
|
versionMadeBy,
|
|
8380
8568
|
comment,
|
|
8381
8569
|
lastModDate,
|
|
8570
|
+
rawLastModDate,
|
|
8382
8571
|
creationDate,
|
|
8383
8572
|
lastAccessDate,
|
|
8384
8573
|
uncompressedSize,
|
|
@@ -8389,6 +8578,7 @@
|
|
|
8389
8578
|
extraFieldAES,
|
|
8390
8579
|
internalFileAttributes,
|
|
8391
8580
|
extraField,
|
|
8581
|
+
bitFlag,
|
|
8392
8582
|
uid,
|
|
8393
8583
|
gid
|
|
8394
8584
|
} = child.data;
|
|
@@ -8426,6 +8616,16 @@
|
|
|
8426
8616
|
encryptionStrength,
|
|
8427
8617
|
compressionMethod
|
|
8428
8618
|
};
|
|
8619
|
+
if (bitFlag) {
|
|
8620
|
+
passThroughOptions.dataDescriptor = bitFlag.dataDescriptor;
|
|
8621
|
+
}
|
|
8622
|
+
const lastModDateOverride = childOptions.lastModDate === UNDEFINED_VALUE ? options.lastModDate : childOptions.lastModDate;
|
|
8623
|
+
if (lastModDateOverride === UNDEFINED_VALUE) {
|
|
8624
|
+
passThroughOptions.rawLastModDate = rawLastModDate;
|
|
8625
|
+
} else if (zipCrypto && (!bitFlag || bitFlag.dataDescriptor) && lastModDateOverride instanceof Date &&
|
|
8626
|
+
getDosTimeHighByte(lastModDateOverride) != ((rawLastModDate >>> 8) & MAX_8_BITS)) {
|
|
8627
|
+
throw new Error(ERR_ZIP_CRYPTO_LAST_MOD_DATE);
|
|
8628
|
+
}
|
|
8429
8629
|
}
|
|
8430
8630
|
}
|
|
8431
8631
|
const entryOptions = Object.assign({ lastModDate: child.defaultLastModDate }, zipEntryMetadata, options, childOptions, passThroughOptions, { directory: child.directory });
|
|
@@ -8435,6 +8635,16 @@
|
|
|
8435
8635
|
return { name, entryOptions };
|
|
8436
8636
|
}
|
|
8437
8637
|
|
|
8638
|
+
function getDosTimeHighByte(lastModDate) {
|
|
8639
|
+
let dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
8640
|
+
if (dosLastModDate < MIN_DATE) {
|
|
8641
|
+
dosLastModDate = MIN_DATE;
|
|
8642
|
+
} else if (dosLastModDate > MAX_DATE) {
|
|
8643
|
+
dosLastModDate = MAX_DATE;
|
|
8644
|
+
}
|
|
8645
|
+
return ((dosLastModDate.getHours() << 3) | (dosLastModDate.getMinutes() >> 3)) & MAX_8_BITS;
|
|
8646
|
+
}
|
|
8647
|
+
|
|
8438
8648
|
function getDeterminedSize(child, passThrough) {
|
|
8439
8649
|
const { reader } = child;
|
|
8440
8650
|
if (reader && reader.size !== UNDEFINED_VALUE) {
|
|
@@ -8778,6 +8988,7 @@
|
|
|
8778
8988
|
exports.ERR_INVALID_PASS_THROUGH = ERR_INVALID_PASS_THROUGH;
|
|
8779
8989
|
exports.ERR_INVALID_READER_OPTIONS = ERR_INVALID_READER_OPTIONS;
|
|
8780
8990
|
exports.ERR_READABLE_CONSUMED = ERR_READABLE_CONSUMED;
|
|
8991
|
+
exports.ERR_ZIP_CRYPTO_LAST_MOD_DATE = ERR_ZIP_CRYPTO_LAST_MOD_DATE;
|
|
8781
8992
|
exports.ZipDirectoryEntry = ZipDirectoryEntry;
|
|
8782
8993
|
exports.ZipEntry = ZipEntry;
|
|
8783
8994
|
exports.ZipFS = ZipFS;
|