@zip.js/zip.js 2.6.60 → 2.6.61
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/dist/zip-fs-full.js +102 -28
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +102 -28
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +102 -28
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +102 -28
- package/dist/zip.min.js +1 -1
- package/index.cjs +102 -28
- package/index.d.ts +6 -0
- package/lib/core/zip-reader.js +8 -5
- package/lib/core/zip-writer.js +94 -23
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -8531,12 +8531,9 @@ class ZipReader {
|
|
|
8531
8531
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
8532
8532
|
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
8533
8533
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
8534
|
-
|
|
8534
|
+
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
8535
8535
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
8536
8536
|
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
8537
|
-
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
8538
|
-
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
8539
|
-
}
|
|
8540
8537
|
let filesLength = getUint16(endOfDirectoryView, 8);
|
|
8541
8538
|
let prependedDataLength = 0;
|
|
8542
8539
|
let startOffset = 0;
|
|
@@ -8560,8 +8557,11 @@ class ZipReader {
|
|
|
8560
8557
|
if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
8561
8558
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
8562
8559
|
}
|
|
8560
|
+
if (lastDiskNumber == MAX_16_BITS) {
|
|
8561
|
+
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
8562
|
+
}
|
|
8563
8563
|
if (diskNumber == MAX_16_BITS) {
|
|
8564
|
-
diskNumber = getUint32(endOfDirectoryView,
|
|
8564
|
+
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
8565
8565
|
}
|
|
8566
8566
|
if (filesLength == MAX_16_BITS) {
|
|
8567
8567
|
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
@@ -8571,6 +8571,9 @@ class ZipReader {
|
|
|
8571
8571
|
}
|
|
8572
8572
|
directoryDataOffset -= directoryDataLength;
|
|
8573
8573
|
}
|
|
8574
|
+
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
8575
|
+
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
8576
|
+
}
|
|
8574
8577
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
8575
8578
|
throw new Error(ERR_BAD_FORMAT);
|
|
8576
8579
|
}
|
|
@@ -9067,7 +9070,6 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
|
9067
9070
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
|
|
9068
9071
|
|
|
9069
9072
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
9070
|
-
const EXTRAFIELD_LENGTH_ZIP64 = 28;
|
|
9071
9073
|
|
|
9072
9074
|
let workers = 0;
|
|
9073
9075
|
const pendingEntries = [];
|
|
@@ -9210,6 +9212,7 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
9210
9212
|
let maximumCompressedSize = 0;
|
|
9211
9213
|
let maximumEntrySize = 0;
|
|
9212
9214
|
let uncompressedSize = 0;
|
|
9215
|
+
const zip64Enabled = zip64 === true;
|
|
9213
9216
|
if (reader) {
|
|
9214
9217
|
reader = initReader(reader);
|
|
9215
9218
|
await initStream(reader);
|
|
@@ -9225,10 +9228,12 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
9225
9228
|
}
|
|
9226
9229
|
}
|
|
9227
9230
|
const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9231
|
+
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
9232
|
+
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
9233
|
+
const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
|
|
9234
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
9235
|
+
const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
|
|
9236
|
+
if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
|
|
9232
9237
|
if (zip64 === false || !keepOrder) {
|
|
9233
9238
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
9234
9239
|
} else {
|
|
@@ -9246,6 +9251,10 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
9246
9251
|
creationDate,
|
|
9247
9252
|
rawExtraField,
|
|
9248
9253
|
zip64,
|
|
9254
|
+
zip64UncompressedSize,
|
|
9255
|
+
zip64CompressedSize,
|
|
9256
|
+
zip64Offset,
|
|
9257
|
+
zip64DiskNumberStart,
|
|
9249
9258
|
password,
|
|
9250
9259
|
level,
|
|
9251
9260
|
useWebWorkers,
|
|
@@ -9343,7 +9352,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
9343
9352
|
await requestLockWriter();
|
|
9344
9353
|
writingBufferedEntryData = true;
|
|
9345
9354
|
if (!dataDescriptor) {
|
|
9346
|
-
blob = await
|
|
9355
|
+
blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
|
|
9347
9356
|
}
|
|
9348
9357
|
await skipDiskIfNeeded(writable);
|
|
9349
9358
|
fileEntry.diskNumberStart = writer.diskNumber;
|
|
@@ -9354,7 +9363,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
9354
9363
|
}
|
|
9355
9364
|
fileEntry.offset = zipWriter.offset - diskOffset;
|
|
9356
9365
|
if (fileEntry.zip64) {
|
|
9357
|
-
|
|
9366
|
+
setZip64ExtraInfo(fileEntry, options);
|
|
9358
9367
|
} else if (fileEntry.offset >= MAX_32_BITS) {
|
|
9359
9368
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
9360
9369
|
}
|
|
@@ -9392,7 +9401,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
9392
9401
|
|
|
9393
9402
|
async function requestLockWriter() {
|
|
9394
9403
|
zipWriter.writerLocked = true;
|
|
9395
|
-
const { lockWriter } = zipWriter;
|
|
9404
|
+
const { lockWriter } = zipWriter;
|
|
9396
9405
|
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
9397
9406
|
zipWriter.writerLocked = false;
|
|
9398
9407
|
resolve();
|
|
@@ -9434,6 +9443,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
9434
9443
|
password,
|
|
9435
9444
|
level,
|
|
9436
9445
|
zip64,
|
|
9446
|
+
zip64UncompressedSize,
|
|
9447
|
+
zip64CompressedSize,
|
|
9448
|
+
zip64Offset,
|
|
9449
|
+
zip64DiskNumberStart,
|
|
9437
9450
|
zipCrypto,
|
|
9438
9451
|
dataDescriptor,
|
|
9439
9452
|
directory,
|
|
@@ -9506,7 +9519,25 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
9506
9519
|
} else {
|
|
9507
9520
|
await writeData(writable, localHeaderArray);
|
|
9508
9521
|
}
|
|
9509
|
-
|
|
9522
|
+
let rawExtraFieldZip64;
|
|
9523
|
+
if (zip64) {
|
|
9524
|
+
let rawExtraFieldZip64Length = 4;
|
|
9525
|
+
if (zip64UncompressedSize) {
|
|
9526
|
+
rawExtraFieldZip64Length += 8;
|
|
9527
|
+
}
|
|
9528
|
+
if (zip64CompressedSize) {
|
|
9529
|
+
rawExtraFieldZip64Length += 8;
|
|
9530
|
+
}
|
|
9531
|
+
if (zip64Offset) {
|
|
9532
|
+
rawExtraFieldZip64Length += 8;
|
|
9533
|
+
}
|
|
9534
|
+
if (zip64DiskNumberStart) {
|
|
9535
|
+
rawExtraFieldZip64Length += 4;
|
|
9536
|
+
}
|
|
9537
|
+
rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
|
|
9538
|
+
} else {
|
|
9539
|
+
rawExtraFieldZip64 = new Uint8Array();
|
|
9540
|
+
}
|
|
9510
9541
|
if (reader) {
|
|
9511
9542
|
setEntryInfo({
|
|
9512
9543
|
signature,
|
|
@@ -9521,6 +9552,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
9521
9552
|
await writeData(writable, dataDescriptorArray);
|
|
9522
9553
|
}
|
|
9523
9554
|
Object.assign(fileEntry, {
|
|
9555
|
+
uncompressedSize,
|
|
9524
9556
|
compressedSize,
|
|
9525
9557
|
lastModDate,
|
|
9526
9558
|
rawLastModDate,
|
|
@@ -9532,7 +9564,11 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
9532
9564
|
version,
|
|
9533
9565
|
headerArray,
|
|
9534
9566
|
signature,
|
|
9535
|
-
rawExtraFieldZip64
|
|
9567
|
+
rawExtraFieldZip64,
|
|
9568
|
+
zip64UncompressedSize,
|
|
9569
|
+
zip64CompressedSize,
|
|
9570
|
+
zip64Offset,
|
|
9571
|
+
zip64DiskNumberStart
|
|
9536
9572
|
});
|
|
9537
9573
|
return fileEntry;
|
|
9538
9574
|
}
|
|
@@ -9709,6 +9745,8 @@ function setEntryInfo(entryInfo, options) {
|
|
|
9709
9745
|
} = dataDescriptorInfo;
|
|
9710
9746
|
const {
|
|
9711
9747
|
zip64,
|
|
9748
|
+
zip64UncompressedSize,
|
|
9749
|
+
zip64CompressedSize,
|
|
9712
9750
|
zipCrypto,
|
|
9713
9751
|
dataDescriptor
|
|
9714
9752
|
} = options;
|
|
@@ -9721,11 +9759,17 @@ function setEntryInfo(entryInfo, options) {
|
|
|
9721
9759
|
if (zip64) {
|
|
9722
9760
|
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
9723
9761
|
setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
|
|
9724
|
-
setUint16(rawExtraFieldZip64View, 2,
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9762
|
+
setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
|
|
9763
|
+
let rawExtraFieldZip64Offset = 4;
|
|
9764
|
+
if (zip64UncompressedSize) {
|
|
9765
|
+
setUint32(headerView, 18, MAX_32_BITS);
|
|
9766
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
9767
|
+
rawExtraFieldZip64Offset += 8;
|
|
9768
|
+
}
|
|
9769
|
+
if (zip64CompressedSize) {
|
|
9770
|
+
setUint32(headerView, 14, MAX_32_BITS);
|
|
9771
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
|
|
9772
|
+
}
|
|
9729
9773
|
if (dataDescriptor) {
|
|
9730
9774
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
|
|
9731
9775
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
|
|
@@ -9740,7 +9784,7 @@ function setEntryInfo(entryInfo, options) {
|
|
|
9740
9784
|
}
|
|
9741
9785
|
}
|
|
9742
9786
|
|
|
9743
|
-
async function
|
|
9787
|
+
async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
|
|
9744
9788
|
const arrayBuffer = await sliceAsArrayBuffer(entryData, 0, 26);
|
|
9745
9789
|
const arrayBufferView = new DataView(arrayBuffer);
|
|
9746
9790
|
if (!fileEntry.encrypted || zipCrypto) {
|
|
@@ -9757,11 +9801,24 @@ async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypt
|
|
|
9757
9801
|
return entryData.slice(arrayBuffer.byteLength);
|
|
9758
9802
|
}
|
|
9759
9803
|
|
|
9760
|
-
function
|
|
9804
|
+
function setZip64ExtraInfo(fileEntry, options) {
|
|
9761
9805
|
const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
|
|
9806
|
+
const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
|
|
9762
9807
|
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
9763
|
-
|
|
9764
|
-
|
|
9808
|
+
let rawExtraFieldZip64Offset = 4;
|
|
9809
|
+
if (zip64UncompressedSize) {
|
|
9810
|
+
rawExtraFieldZip64Offset += 8;
|
|
9811
|
+
}
|
|
9812
|
+
if (zip64CompressedSize) {
|
|
9813
|
+
rawExtraFieldZip64Offset += 8;
|
|
9814
|
+
}
|
|
9815
|
+
if (zip64Offset) {
|
|
9816
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
|
|
9817
|
+
rawExtraFieldZip64Offset += 8;
|
|
9818
|
+
}
|
|
9819
|
+
if (zip64DiskNumberStart) {
|
|
9820
|
+
setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
|
|
9821
|
+
}
|
|
9765
9822
|
}
|
|
9766
9823
|
|
|
9767
9824
|
async function closeFile(zipWriter, comment, options) {
|
|
@@ -9808,12 +9865,18 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
9808
9865
|
headerArray,
|
|
9809
9866
|
directory,
|
|
9810
9867
|
zip64,
|
|
9868
|
+
zip64UncompressedSize,
|
|
9869
|
+
zip64CompressedSize,
|
|
9870
|
+
zip64DiskNumberStart,
|
|
9871
|
+
zip64Offset,
|
|
9811
9872
|
msDosCompatible,
|
|
9812
9873
|
internalFileAttribute,
|
|
9813
9874
|
externalFileAttribute,
|
|
9814
9875
|
extendedTimestamp,
|
|
9815
9876
|
lastModDate,
|
|
9816
|
-
diskNumberStart
|
|
9877
|
+
diskNumberStart,
|
|
9878
|
+
uncompressedSize,
|
|
9879
|
+
compressedSize
|
|
9817
9880
|
} = fileEntry;
|
|
9818
9881
|
let rawExtraFieldExtendedTimestamp;
|
|
9819
9882
|
if (extendedTimestamp) {
|
|
@@ -9829,17 +9892,24 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
9829
9892
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
9830
9893
|
setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
9831
9894
|
setUint16(directoryView, offset + 4, versionMadeBy);
|
|
9895
|
+
const headerView = getDataView(headerArray);
|
|
9896
|
+
if (!zip64UncompressedSize) {
|
|
9897
|
+
setUint32(headerView, 18, uncompressedSize);
|
|
9898
|
+
}
|
|
9899
|
+
if (!zip64CompressedSize) {
|
|
9900
|
+
setUint32(headerView, 14, compressedSize);
|
|
9901
|
+
}
|
|
9832
9902
|
arraySet(directoryArray, headerArray, offset + 6);
|
|
9833
9903
|
setUint16(directoryView, offset + 30, extraFieldLength);
|
|
9834
9904
|
setUint16(directoryView, offset + 32, getLength(rawComment));
|
|
9835
|
-
setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
|
|
9905
|
+
setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
9836
9906
|
setUint16(directoryView, offset + 36, internalFileAttribute);
|
|
9837
9907
|
if (externalFileAttribute) {
|
|
9838
9908
|
setUint32(directoryView, offset + 38, externalFileAttribute);
|
|
9839
9909
|
} else if (directory && msDosCompatible) {
|
|
9840
9910
|
setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
|
|
9841
9911
|
}
|
|
9842
|
-
setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
|
|
9912
|
+
setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
9843
9913
|
arraySet(directoryArray, rawFilename, offset + 46);
|
|
9844
9914
|
arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
|
|
9845
9915
|
arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
|
|
@@ -9893,7 +9963,11 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
9893
9963
|
setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
9894
9964
|
setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
|
|
9895
9965
|
setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
|
|
9896
|
-
|
|
9966
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
9967
|
+
if (supportZip64SplitFile) {
|
|
9968
|
+
lastDiskNumber = MAX_16_BITS;
|
|
9969
|
+
diskNumber = MAX_16_BITS;
|
|
9970
|
+
}
|
|
9897
9971
|
filesLength = MAX_16_BITS;
|
|
9898
9972
|
directoryOffset = MAX_32_BITS;
|
|
9899
9973
|
directoryDataLength = MAX_32_BITS;
|
package/index.d.ts
CHANGED
|
@@ -1106,6 +1106,12 @@ interface ZipWriterConstructorOptions {
|
|
|
1106
1106
|
* @defaultValue 0
|
|
1107
1107
|
*/
|
|
1108
1108
|
internalFileAttribute?: number
|
|
1109
|
+
/**
|
|
1110
|
+
* `false` to never write disk numbers in zip64 data.
|
|
1111
|
+
*
|
|
1112
|
+
* @defaultValue true
|
|
1113
|
+
*/
|
|
1114
|
+
supportZip64SplitFile?: boolean
|
|
1109
1115
|
}
|
|
1110
1116
|
|
|
1111
1117
|
/**
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -165,12 +165,9 @@ class ZipReader {
|
|
|
165
165
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
166
166
|
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
167
167
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
168
|
-
|
|
168
|
+
let lastDiskNumber = getUint16(endOfDirectoryView, 4);
|
|
169
169
|
const expectedLastDiskNumber = reader.lastDiskNumber || 0;
|
|
170
170
|
let diskNumber = getUint16(endOfDirectoryView, 6);
|
|
171
|
-
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
172
|
-
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
173
|
-
}
|
|
174
171
|
let filesLength = getUint16(endOfDirectoryView, 8);
|
|
175
172
|
let prependedDataLength = 0;
|
|
176
173
|
let startOffset = 0;
|
|
@@ -194,8 +191,11 @@ class ZipReader {
|
|
|
194
191
|
if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
195
192
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
196
193
|
}
|
|
194
|
+
if (lastDiskNumber == MAX_16_BITS) {
|
|
195
|
+
lastDiskNumber = getUint32(endOfDirectoryView, 16);
|
|
196
|
+
}
|
|
197
197
|
if (diskNumber == MAX_16_BITS) {
|
|
198
|
-
diskNumber = getUint32(endOfDirectoryView,
|
|
198
|
+
diskNumber = getUint32(endOfDirectoryView, 20);
|
|
199
199
|
}
|
|
200
200
|
if (filesLength == MAX_16_BITS) {
|
|
201
201
|
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
@@ -205,6 +205,9 @@ class ZipReader {
|
|
|
205
205
|
}
|
|
206
206
|
directoryDataOffset -= directoryDataLength;
|
|
207
207
|
}
|
|
208
|
+
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
209
|
+
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
210
|
+
}
|
|
208
211
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
209
212
|
throw new Error(ERR_BAD_FORMAT);
|
|
210
213
|
}
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -101,7 +101,6 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
|
101
101
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
|
|
102
102
|
|
|
103
103
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
104
|
-
const EXTRAFIELD_LENGTH_ZIP64 = 28;
|
|
105
104
|
|
|
106
105
|
let workers = 0;
|
|
107
106
|
const pendingEntries = [];
|
|
@@ -257,6 +256,7 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
257
256
|
let maximumCompressedSize = 0;
|
|
258
257
|
let maximumEntrySize = 0;
|
|
259
258
|
let uncompressedSize = 0;
|
|
259
|
+
const zip64Enabled = zip64 === true;
|
|
260
260
|
if (reader) {
|
|
261
261
|
reader = initReader(reader);
|
|
262
262
|
await initStream(reader);
|
|
@@ -272,10 +272,12 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
276
|
+
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
277
|
+
const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset >= MAX_32_BITS;
|
|
278
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
279
|
+
const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) >= MAX_16_BITS;
|
|
280
|
+
if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
|
|
279
281
|
if (zip64 === false || !keepOrder) {
|
|
280
282
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
281
283
|
} else {
|
|
@@ -293,6 +295,10 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
293
295
|
creationDate,
|
|
294
296
|
rawExtraField,
|
|
295
297
|
zip64,
|
|
298
|
+
zip64UncompressedSize,
|
|
299
|
+
zip64CompressedSize,
|
|
300
|
+
zip64Offset,
|
|
301
|
+
zip64DiskNumberStart,
|
|
296
302
|
password,
|
|
297
303
|
level,
|
|
298
304
|
useWebWorkers,
|
|
@@ -390,7 +396,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
390
396
|
await requestLockWriter();
|
|
391
397
|
writingBufferedEntryData = true;
|
|
392
398
|
if (!dataDescriptor) {
|
|
393
|
-
blob = await
|
|
399
|
+
blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
|
|
394
400
|
}
|
|
395
401
|
await skipDiskIfNeeded(writable);
|
|
396
402
|
fileEntry.diskNumberStart = writer.diskNumber;
|
|
@@ -401,7 +407,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
401
407
|
}
|
|
402
408
|
fileEntry.offset = zipWriter.offset - diskOffset;
|
|
403
409
|
if (fileEntry.zip64) {
|
|
404
|
-
|
|
410
|
+
setZip64ExtraInfo(fileEntry, options);
|
|
405
411
|
} else if (fileEntry.offset >= MAX_32_BITS) {
|
|
406
412
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
407
413
|
}
|
|
@@ -439,7 +445,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
439
445
|
|
|
440
446
|
async function requestLockWriter() {
|
|
441
447
|
zipWriter.writerLocked = true;
|
|
442
|
-
const { lockWriter } = zipWriter;
|
|
448
|
+
const { lockWriter } = zipWriter;
|
|
443
449
|
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
444
450
|
zipWriter.writerLocked = false;
|
|
445
451
|
resolve();
|
|
@@ -481,6 +487,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
481
487
|
password,
|
|
482
488
|
level,
|
|
483
489
|
zip64,
|
|
490
|
+
zip64UncompressedSize,
|
|
491
|
+
zip64CompressedSize,
|
|
492
|
+
zip64Offset,
|
|
493
|
+
zip64DiskNumberStart,
|
|
484
494
|
zipCrypto,
|
|
485
495
|
dataDescriptor,
|
|
486
496
|
directory,
|
|
@@ -553,7 +563,25 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
553
563
|
} else {
|
|
554
564
|
await writeData(writable, localHeaderArray);
|
|
555
565
|
}
|
|
556
|
-
|
|
566
|
+
let rawExtraFieldZip64;
|
|
567
|
+
if (zip64) {
|
|
568
|
+
let rawExtraFieldZip64Length = 4;
|
|
569
|
+
if (zip64UncompressedSize) {
|
|
570
|
+
rawExtraFieldZip64Length += 8;
|
|
571
|
+
}
|
|
572
|
+
if (zip64CompressedSize) {
|
|
573
|
+
rawExtraFieldZip64Length += 8;
|
|
574
|
+
}
|
|
575
|
+
if (zip64Offset) {
|
|
576
|
+
rawExtraFieldZip64Length += 8;
|
|
577
|
+
}
|
|
578
|
+
if (zip64DiskNumberStart) {
|
|
579
|
+
rawExtraFieldZip64Length += 4;
|
|
580
|
+
}
|
|
581
|
+
rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
|
|
582
|
+
} else {
|
|
583
|
+
rawExtraFieldZip64 = new Uint8Array();
|
|
584
|
+
}
|
|
557
585
|
if (reader) {
|
|
558
586
|
setEntryInfo({
|
|
559
587
|
signature,
|
|
@@ -568,6 +596,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
568
596
|
await writeData(writable, dataDescriptorArray);
|
|
569
597
|
}
|
|
570
598
|
Object.assign(fileEntry, {
|
|
599
|
+
uncompressedSize,
|
|
571
600
|
compressedSize,
|
|
572
601
|
lastModDate,
|
|
573
602
|
rawLastModDate,
|
|
@@ -579,7 +608,11 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
579
608
|
version,
|
|
580
609
|
headerArray,
|
|
581
610
|
signature,
|
|
582
|
-
rawExtraFieldZip64
|
|
611
|
+
rawExtraFieldZip64,
|
|
612
|
+
zip64UncompressedSize,
|
|
613
|
+
zip64CompressedSize,
|
|
614
|
+
zip64Offset,
|
|
615
|
+
zip64DiskNumberStart
|
|
583
616
|
});
|
|
584
617
|
return fileEntry;
|
|
585
618
|
}
|
|
@@ -756,6 +789,8 @@ function setEntryInfo(entryInfo, options) {
|
|
|
756
789
|
} = dataDescriptorInfo;
|
|
757
790
|
const {
|
|
758
791
|
zip64,
|
|
792
|
+
zip64UncompressedSize,
|
|
793
|
+
zip64CompressedSize,
|
|
759
794
|
zipCrypto,
|
|
760
795
|
dataDescriptor
|
|
761
796
|
} = options;
|
|
@@ -768,11 +803,17 @@ function setEntryInfo(entryInfo, options) {
|
|
|
768
803
|
if (zip64) {
|
|
769
804
|
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
770
805
|
setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
|
|
771
|
-
setUint16(rawExtraFieldZip64View, 2,
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
806
|
+
setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
|
|
807
|
+
let rawExtraFieldZip64Offset = 4;
|
|
808
|
+
if (zip64UncompressedSize) {
|
|
809
|
+
setUint32(headerView, 18, MAX_32_BITS);
|
|
810
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
811
|
+
rawExtraFieldZip64Offset += 8;
|
|
812
|
+
}
|
|
813
|
+
if (zip64CompressedSize) {
|
|
814
|
+
setUint32(headerView, 14, MAX_32_BITS);
|
|
815
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
|
|
816
|
+
}
|
|
776
817
|
if (dataDescriptor) {
|
|
777
818
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
|
|
778
819
|
setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
|
|
@@ -787,7 +828,7 @@ function setEntryInfo(entryInfo, options) {
|
|
|
787
828
|
}
|
|
788
829
|
}
|
|
789
830
|
|
|
790
|
-
async function
|
|
831
|
+
async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
|
|
791
832
|
const arrayBuffer = await sliceAsArrayBuffer(entryData, 0, 26);
|
|
792
833
|
const arrayBufferView = new DataView(arrayBuffer);
|
|
793
834
|
if (!fileEntry.encrypted || zipCrypto) {
|
|
@@ -804,11 +845,24 @@ async function writeMissingHeaderInfo(fileEntry, entryData, writable, { zipCrypt
|
|
|
804
845
|
return entryData.slice(arrayBuffer.byteLength);
|
|
805
846
|
}
|
|
806
847
|
|
|
807
|
-
function
|
|
848
|
+
function setZip64ExtraInfo(fileEntry, options) {
|
|
808
849
|
const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
|
|
850
|
+
const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
|
|
809
851
|
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
810
|
-
|
|
811
|
-
|
|
852
|
+
let rawExtraFieldZip64Offset = 4;
|
|
853
|
+
if (zip64UncompressedSize) {
|
|
854
|
+
rawExtraFieldZip64Offset += 8;
|
|
855
|
+
}
|
|
856
|
+
if (zip64CompressedSize) {
|
|
857
|
+
rawExtraFieldZip64Offset += 8;
|
|
858
|
+
}
|
|
859
|
+
if (zip64Offset) {
|
|
860
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
|
|
861
|
+
rawExtraFieldZip64Offset += 8;
|
|
862
|
+
}
|
|
863
|
+
if (zip64DiskNumberStart) {
|
|
864
|
+
setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
|
|
865
|
+
}
|
|
812
866
|
}
|
|
813
867
|
|
|
814
868
|
async function closeFile(zipWriter, comment, options) {
|
|
@@ -855,12 +909,18 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
855
909
|
headerArray,
|
|
856
910
|
directory,
|
|
857
911
|
zip64,
|
|
912
|
+
zip64UncompressedSize,
|
|
913
|
+
zip64CompressedSize,
|
|
914
|
+
zip64DiskNumberStart,
|
|
915
|
+
zip64Offset,
|
|
858
916
|
msDosCompatible,
|
|
859
917
|
internalFileAttribute,
|
|
860
918
|
externalFileAttribute,
|
|
861
919
|
extendedTimestamp,
|
|
862
920
|
lastModDate,
|
|
863
|
-
diskNumberStart
|
|
921
|
+
diskNumberStart,
|
|
922
|
+
uncompressedSize,
|
|
923
|
+
compressedSize
|
|
864
924
|
} = fileEntry;
|
|
865
925
|
let rawExtraFieldExtendedTimestamp;
|
|
866
926
|
if (extendedTimestamp) {
|
|
@@ -876,17 +936,24 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
876
936
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
877
937
|
setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
878
938
|
setUint16(directoryView, offset + 4, versionMadeBy);
|
|
939
|
+
const headerView = getDataView(headerArray);
|
|
940
|
+
if (!zip64UncompressedSize) {
|
|
941
|
+
setUint32(headerView, 18, uncompressedSize);
|
|
942
|
+
}
|
|
943
|
+
if (!zip64CompressedSize) {
|
|
944
|
+
setUint32(headerView, 14, compressedSize);
|
|
945
|
+
}
|
|
879
946
|
arraySet(directoryArray, headerArray, offset + 6);
|
|
880
947
|
setUint16(directoryView, offset + 30, extraFieldLength);
|
|
881
948
|
setUint16(directoryView, offset + 32, getLength(rawComment));
|
|
882
|
-
setUint16(directoryView, offset + 34, zip64 ? MAX_16_BITS : diskNumberStart);
|
|
949
|
+
setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
883
950
|
setUint16(directoryView, offset + 36, internalFileAttribute);
|
|
884
951
|
if (externalFileAttribute) {
|
|
885
952
|
setUint32(directoryView, offset + 38, externalFileAttribute);
|
|
886
953
|
} else if (directory && msDosCompatible) {
|
|
887
954
|
setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
|
|
888
955
|
}
|
|
889
|
-
setUint32(directoryView, offset + 42, zip64 ? MAX_32_BITS : fileEntryOffset);
|
|
956
|
+
setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
890
957
|
arraySet(directoryArray, rawFilename, offset + 46);
|
|
891
958
|
arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
|
|
892
959
|
arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
|
|
@@ -940,7 +1007,11 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
940
1007
|
setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
941
1008
|
setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
|
|
942
1009
|
setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
|
|
943
|
-
|
|
1010
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
1011
|
+
if (supportZip64SplitFile) {
|
|
1012
|
+
lastDiskNumber = MAX_16_BITS;
|
|
1013
|
+
diskNumber = MAX_16_BITS;
|
|
1014
|
+
}
|
|
944
1015
|
filesLength = MAX_16_BITS;
|
|
945
1016
|
directoryOffset = MAX_32_BITS;
|
|
946
1017
|
directoryDataLength = MAX_32_BITS;
|
package/package.json
CHANGED