@zip.js/zip.js 2.8.55 → 2.8.57
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 +90 -52
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +90 -51
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +102 -60
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +101 -59
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +102 -60
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +102 -59
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +102 -59
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +90 -51
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +90 -51
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +90 -51
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +102 -59
- package/index-native.min.js +1 -1
- package/index.cjs +102 -59
- package/index.d.cts +18 -1
- package/index.d.ts +18 -1
- package/index.min.js +1 -1
- package/lib/core/options.js +14 -0
- package/lib/core/zip-fs.js +1 -1
- package/lib/core/zip-reader.js +19 -5
- package/lib/core/zip-writer.js +73 -55
- package/lib/zip-core-reader.js +1 -0
- package/package.json +1 -1
package/lib/core/options.js
CHANGED
|
@@ -141,6 +141,8 @@ export {
|
|
|
141
141
|
checkFunctionOption,
|
|
142
142
|
checkSignalOption,
|
|
143
143
|
checkPasswordOption,
|
|
144
|
+
checkInteger,
|
|
145
|
+
checkIntegerOption,
|
|
144
146
|
toNumber
|
|
145
147
|
};
|
|
146
148
|
|
|
@@ -164,6 +166,18 @@ function checkPasswordOption(password, rawPassword) {
|
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
168
|
|
|
169
|
+
function checkInteger(value, maxValue, errorMessage) {
|
|
170
|
+
if (!Number.isInteger(value) || value < 0 || value > maxValue) {
|
|
171
|
+
throw new Error(errorMessage);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function checkIntegerOption(value, maxValue, errorMessage) {
|
|
176
|
+
if (value !== UNDEFINED_VALUE) {
|
|
177
|
+
checkInteger(value, maxValue, errorMessage);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
167
181
|
function toNumber(value) {
|
|
168
182
|
return typeof value == STRING_TYPE && value.trim() ? Number(value) : value;
|
|
169
183
|
}
|
package/lib/core/zip-fs.js
CHANGED
|
@@ -838,7 +838,7 @@ function keepsContentType(writer, data) {
|
|
|
838
838
|
} else if (writer.constructor == BlobWriter) {
|
|
839
839
|
return data.type == contentType;
|
|
840
840
|
} else if (writer.constructor == Data64URIWriter) {
|
|
841
|
-
return data.startsWith(
|
|
841
|
+
return data.startsWith("data:" + (contentType || "") + ";base64,");
|
|
842
842
|
} else {
|
|
843
843
|
return true;
|
|
844
844
|
}
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -194,6 +194,7 @@ const ERR_UNSAFE_FILENAME = "Unsafe filename";
|
|
|
194
194
|
const ERR_INVALID_STRICTNESS = "Invalid strictness (must be 'strict', 'balanced' or 'tolerant')";
|
|
195
195
|
const ERR_INVALID_FILENAME_VALIDATION = "Invalid filenameValidation (must be 'strict', 'balanced' or 'tolerant')";
|
|
196
196
|
const ERR_INVALID_MAX_APPENDED_DATA_SIZE = "Invalid maxAppendedDataSize (must be a number greater than or equal to 0)";
|
|
197
|
+
const ERR_UNSUPPORTED_UINT64 = "64-bit value exceeds Number.MAX_SAFE_INTEGER";
|
|
197
198
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
198
199
|
const CHARSET_UTF8 = "utf-8";
|
|
199
200
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
@@ -216,6 +217,7 @@ const ZIP64_EXTRACTION = {
|
|
|
216
217
|
bytes: 8
|
|
217
218
|
}
|
|
218
219
|
};
|
|
220
|
+
const MAX_SAFE_UINT64 = BigInt(Number.MAX_SAFE_INTEGER);
|
|
219
221
|
const MAX_END_OF_CENTRAL_DIR_PROBES = 64;
|
|
220
222
|
const MAX_DEFLATE_EXPANSION_RATIO = 1032;
|
|
221
223
|
const CENTRAL_DIRECTORY_UNREACHABLE = 0;
|
|
@@ -311,7 +313,7 @@ class ZipReader {
|
|
|
311
313
|
zip64EndOfDirectoryVersion2 = getBigUint64(endOfDirectoryView, 4) > ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12;
|
|
312
314
|
if (zip64EndOfDirectoryVersion2) {
|
|
313
315
|
const extensibleDataLength = Math.min(
|
|
314
|
-
|
|
316
|
+
getBigUint64(endOfDirectoryView, 4) - (ZIP64_END_OF_CENTRAL_DIR_LENGTH - 12),
|
|
315
317
|
reader.size - directoryDataOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
316
318
|
if (extensibleDataLength > 0) {
|
|
317
319
|
zip64EndOfDirectoryLength += extensibleDataLength;
|
|
@@ -544,8 +546,15 @@ class ZipReader {
|
|
|
544
546
|
yield entry;
|
|
545
547
|
}
|
|
546
548
|
let offsetAfterSignature = offset;
|
|
547
|
-
|
|
549
|
+
let digitalSignature = readDigitalSignature(directoryArray.subarray(offset)) ||
|
|
548
550
|
(decryptedDirectory ? readDigitalSignature(dataAfterEncryptedDirectory) : UNDEFINED_VALUE);
|
|
551
|
+
if (!digitalSignature && !decryptedDirectory) {
|
|
552
|
+
const signatureRecordOffset = directoryDataOffset + offset;
|
|
553
|
+
const signatureRecordLength = Math.min(centralDirectoryEndOffset - signatureRecordOffset, 6 + MAX_16_BITS);
|
|
554
|
+
if (signatureRecordLength >= 6) {
|
|
555
|
+
digitalSignature = readDigitalSignature(await readUint8Array(reader, signatureRecordOffset, signatureRecordLength));
|
|
556
|
+
}
|
|
557
|
+
}
|
|
549
558
|
if (digitalSignature) {
|
|
550
559
|
zipReader.digitalSignature = digitalSignature;
|
|
551
560
|
offsetAfterSignature = offset + 6 + digitalSignature.length;
|
|
@@ -658,6 +667,7 @@ export {
|
|
|
658
667
|
ERR_INVALID_STRICTNESS,
|
|
659
668
|
ERR_INVALID_FILENAME_VALIDATION,
|
|
660
669
|
ERR_INVALID_MAX_APPENDED_DATA_SIZE,
|
|
670
|
+
ERR_UNSUPPORTED_UINT64,
|
|
661
671
|
ERR_WORKER_STARTUP_TIMEOUT
|
|
662
672
|
};
|
|
663
673
|
|
|
@@ -915,8 +925,8 @@ function getDirectoryEncryptionInfo(rawExtensibleData) {
|
|
|
915
925
|
const hashDataLength = getUint16(extensibleDataView, 26);
|
|
916
926
|
Object.assign(directoryEncryptionInfo, {
|
|
917
927
|
compressionMethod: getUint16(extensibleDataView, 0),
|
|
918
|
-
compressedSize:
|
|
919
|
-
uncompressedSize:
|
|
928
|
+
compressedSize: getBigUint64(extensibleDataView, 2),
|
|
929
|
+
uncompressedSize: getBigUint64(extensibleDataView, 10),
|
|
920
930
|
encryptionAlgorithm: getUint16(extensibleDataView, 18),
|
|
921
931
|
bitLength: getUint16(extensibleDataView, 20),
|
|
922
932
|
flags: getUint16(extensibleDataView, 22),
|
|
@@ -1551,5 +1561,9 @@ function getUint32(view, offset) {
|
|
|
1551
1561
|
}
|
|
1552
1562
|
|
|
1553
1563
|
function getBigUint64(view, offset) {
|
|
1554
|
-
|
|
1564
|
+
const value = view.getBigUint64(offset, true);
|
|
1565
|
+
if (value > MAX_SAFE_UINT64) {
|
|
1566
|
+
throw new Error(ERR_UNSUPPORTED_UINT64);
|
|
1567
|
+
}
|
|
1568
|
+
return Number(value);
|
|
1555
1569
|
}
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -170,7 +170,7 @@ import {
|
|
|
170
170
|
ownsWritable
|
|
171
171
|
} from "./io.js";
|
|
172
172
|
import { encodeText } from "./util/encode-text.js";
|
|
173
|
-
import { getDataView } from "./util/array.js";
|
|
173
|
+
import { concat, getDataView } from "./util/array.js";
|
|
174
174
|
import { toCompatibleReadable, streamToBlob } from "./util/compatible-streams.js";
|
|
175
175
|
import {
|
|
176
176
|
PROPERTY_NAME_LAST_MODIFICATION_DATE,
|
|
@@ -235,6 +235,8 @@ import {
|
|
|
235
235
|
checkFunctionOption,
|
|
236
236
|
checkSignalOption,
|
|
237
237
|
checkPasswordOption,
|
|
238
|
+
checkInteger,
|
|
239
|
+
checkIntegerOption,
|
|
238
240
|
toNumber
|
|
239
241
|
} from "./options.js";
|
|
240
242
|
|
|
@@ -276,6 +278,8 @@ const ERR_INVALID_SIGNATURE_DATA = "Signature data exceeds 64KB";
|
|
|
276
278
|
|
|
277
279
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
278
280
|
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
281
|
+
const EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD = 9;
|
|
282
|
+
const EXTRAFIELD_USDZ_MAX_LENGTH = 67;
|
|
279
283
|
const VENDOR_VERSION_AE_1 = 1;
|
|
280
284
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
281
285
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
@@ -322,16 +326,14 @@ class ZipWriter {
|
|
|
322
326
|
await zipReader.close();
|
|
323
327
|
await initStream(this.writer);
|
|
324
328
|
const { directoryOffset } = zipReader;
|
|
325
|
-
let splitZipSignatureLength = 0;
|
|
326
329
|
if (this.addSplitZipSignature) {
|
|
327
330
|
delete this.addSplitZipSignature;
|
|
328
331
|
if (!await startsWithSplitZipSignature(reader)) {
|
|
329
332
|
await writeData(this.writer, getSplitZipSignatureArray());
|
|
330
|
-
|
|
331
|
-
this.offset += splitZipSignatureLength;
|
|
333
|
+
this.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
332
334
|
}
|
|
333
335
|
}
|
|
334
|
-
const entryPositions = await copyZipData(this, reader, entries, directoryOffset
|
|
336
|
+
const entryPositions = await copyZipData(this, reader, entries, directoryOffset);
|
|
335
337
|
this.filenames = new Set(entries.map(entry => entry.filename));
|
|
336
338
|
this.fileEntries = new Map(entries.map(entry => {
|
|
337
339
|
const {
|
|
@@ -344,7 +346,7 @@ class ZipWriter {
|
|
|
344
346
|
encrypted,
|
|
345
347
|
uncompressedSize,
|
|
346
348
|
compressedSize,
|
|
347
|
-
|
|
349
|
+
extraFieldZip64
|
|
348
350
|
} = entry;
|
|
349
351
|
let {
|
|
350
352
|
compressionMethod,
|
|
@@ -361,13 +363,13 @@ class ZipWriter {
|
|
|
361
363
|
rawExtraFieldExtendedTimestamp = rawExtraFieldExtendedTimestamp || EMPTY_UINT8_ARRAY;
|
|
362
364
|
rawExtraFieldNTFS = rawExtraFieldNTFS || EMPTY_UINT8_ARRAY;
|
|
363
365
|
rawExtraFieldUnix = rawExtraFieldUnix || EMPTY_UINT8_ARRAY;
|
|
364
|
-
rawExtraField = rawExtraField || EMPTY_UINT8_ARRAY;
|
|
366
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
365
367
|
if (entry.extraFieldAES) {
|
|
366
368
|
compressionMethod = COMPRESSION_METHOD_AES;
|
|
367
369
|
}
|
|
368
370
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
369
|
-
const zip64UncompressedSize =
|
|
370
|
-
const zip64CompressedSize =
|
|
371
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
372
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
371
373
|
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
372
374
|
const {
|
|
373
375
|
headerArray,
|
|
@@ -611,7 +613,8 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
611
613
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
612
614
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
613
615
|
offset: zipWriter.offset - diskOffset,
|
|
614
|
-
diskNumberStart: diskNumber
|
|
616
|
+
diskNumberStart: diskNumber,
|
|
617
|
+
[OPTION_USDZ]: zipWriter.options[OPTION_USDZ]
|
|
615
618
|
});
|
|
616
619
|
const headerInfo = getHeaderInfo(options);
|
|
617
620
|
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
@@ -643,15 +646,9 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
643
646
|
let setuid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETUID);
|
|
644
647
|
let setgid = getOptionValue(zipWriter, options, PROPERTY_NAME_SETGID);
|
|
645
648
|
let sticky = getOptionValue(zipWriter, options, PROPERTY_NAME_STICKY);
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
if (gid !== UNDEFINED_VALUE && (!Number.isInteger(gid) || gid < 0 || gid > MAX_32_BITS)) {
|
|
650
|
-
throw new Error(ERR_INVALID_GID);
|
|
651
|
-
}
|
|
652
|
-
if (unixMode !== UNDEFINED_VALUE && (!Number.isInteger(unixMode) || unixMode < 0 || unixMode > MAX_16_BITS)) {
|
|
653
|
-
throw new Error(ERR_INVALID_UNIX_MODE);
|
|
654
|
-
}
|
|
649
|
+
checkIntegerOption(uid, MAX_32_BITS, ERR_INVALID_UID);
|
|
650
|
+
checkIntegerOption(gid, MAX_32_BITS, ERR_INVALID_GID);
|
|
651
|
+
checkIntegerOption(unixMode, MAX_16_BITS, ERR_INVALID_UNIX_MODE);
|
|
655
652
|
if (unixExtraFieldType !== UNDEFINED_VALUE && unixExtraFieldType !== INFOZIP_EXTRA_FIELD_TYPE && unixExtraFieldType !== UNIX_EXTRA_FIELD_TYPE) {
|
|
656
653
|
throw new Error(ERR_INVALID_UNIX_EXTRA_FIELD_TYPE);
|
|
657
654
|
}
|
|
@@ -673,9 +670,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
673
670
|
msDosCompatible = true;
|
|
674
671
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
675
672
|
}
|
|
676
|
-
|
|
677
|
-
throw new Error(ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
678
|
-
}
|
|
673
|
+
checkIntegerOption(msdosAttributesRaw, MAX_8_BITS, ERR_INVALID_MSDOS_ATTRIBUTES);
|
|
679
674
|
if (msdosAttributes && (typeof msdosAttributes !== OBJECT_TYPE || Array.isArray(msdosAttributes))) {
|
|
680
675
|
throw new Error(ERR_INVALID_MSDOS_DATA);
|
|
681
676
|
}
|
|
@@ -815,9 +810,7 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
815
810
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
816
811
|
}
|
|
817
812
|
let level = getNumberOptionValue(zipWriter, options, OPTION_LEVEL);
|
|
818
|
-
|
|
819
|
-
throw new Error(ERR_INVALID_LEVEL);
|
|
820
|
-
}
|
|
813
|
+
checkIntegerOption(level, MAX_LEVEL, ERR_INVALID_LEVEL);
|
|
821
814
|
if (zipWriter.options[OPTION_USDZ]) {
|
|
822
815
|
if (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) {
|
|
823
816
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_USDZ);
|
|
@@ -895,9 +888,7 @@ function serializeExtraField(extraField) {
|
|
|
895
888
|
let extraFieldSize = 0;
|
|
896
889
|
let offset = 0;
|
|
897
890
|
extraField.forEach((data, type) => {
|
|
898
|
-
|
|
899
|
-
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
900
|
-
}
|
|
891
|
+
checkInteger(type, MAX_16_BITS, ERR_INVALID_EXTRAFIELD_TYPE);
|
|
901
892
|
if (!(data instanceof Uint8Array)) {
|
|
902
893
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA_TYPE);
|
|
903
894
|
}
|
|
@@ -972,6 +963,10 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
972
963
|
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
973
964
|
}
|
|
974
965
|
}
|
|
966
|
+
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThrough)) && !isCompressed(compressionMethod, level);
|
|
967
|
+
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
968
|
+
dataDescriptor = false;
|
|
969
|
+
}
|
|
975
970
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
976
971
|
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
977
972
|
if (zip64UncompressedSize || zip64CompressedSize) {
|
|
@@ -986,6 +981,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
986
981
|
maximumCompressedSize,
|
|
987
982
|
resolvedOptions: {
|
|
988
983
|
dataDescriptor,
|
|
984
|
+
emptyEntry,
|
|
989
985
|
zip64,
|
|
990
986
|
zip64UncompressedSize,
|
|
991
987
|
zip64CompressedSize,
|
|
@@ -1012,7 +1008,9 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1012
1008
|
const usdz = writerOptions[OPTION_USDZ];
|
|
1013
1009
|
const files = new Map();
|
|
1014
1010
|
let layoutDependsOnWriteOrder = Boolean(usdz);
|
|
1015
|
-
|
|
1011
|
+
const initialOffset = writerOptions[OPTION_OFFSET] === UNDEFINED_VALUE ? 0 : writerOptions[OPTION_OFFSET];
|
|
1012
|
+
let offset = initialOffset;
|
|
1013
|
+
let minimumEntrySize = INFINITY_VALUE;
|
|
1016
1014
|
for (const entry of entries) {
|
|
1017
1015
|
let { name } = entry;
|
|
1018
1016
|
const { size } = entry;
|
|
@@ -1036,7 +1034,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1036
1034
|
if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
1037
1035
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
1038
1036
|
}
|
|
1039
|
-
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
|
|
1037
|
+
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes, { [OPTION_USDZ]: usdz });
|
|
1040
1038
|
const headerInfo = getHeaderInfo(entryOptions);
|
|
1041
1039
|
const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
|
|
1042
1040
|
const entryInfo = {
|
|
@@ -1047,15 +1045,17 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1047
1045
|
appendExtraFieldUSDZ(entryInfo, offset);
|
|
1048
1046
|
}
|
|
1049
1047
|
const compressedSize = hasContent ? maximumCompressedSize : 0;
|
|
1050
|
-
if (offset >= MAX_32_BITS) {
|
|
1051
|
-
layoutDependsOnWriteOrder = true;
|
|
1052
|
-
}
|
|
1053
1048
|
files.set(name, Object.assign({}, entryOptions, headerInfo, {
|
|
1054
1049
|
offset,
|
|
1055
1050
|
diskNumberStart: 0,
|
|
1056
1051
|
compressedSize
|
|
1057
1052
|
}));
|
|
1058
|
-
|
|
1053
|
+
const entrySize = entryInfo.metadataSize + compressedSize;
|
|
1054
|
+
minimumEntrySize = Math.min(minimumEntrySize, entrySize);
|
|
1055
|
+
offset += entrySize;
|
|
1056
|
+
}
|
|
1057
|
+
if (files.size && offset - minimumEntrySize >= MAX_32_BITS) {
|
|
1058
|
+
layoutDependsOnWriteOrder = true;
|
|
1059
1059
|
}
|
|
1060
1060
|
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
1061
1061
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
@@ -1069,7 +1069,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1069
1069
|
zip64 = true;
|
|
1070
1070
|
}
|
|
1071
1071
|
}
|
|
1072
|
-
return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
1072
|
+
return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
1073
1073
|
}
|
|
1074
1074
|
|
|
1075
1075
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
@@ -1080,6 +1080,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1080
1080
|
const {
|
|
1081
1081
|
keepOrder,
|
|
1082
1082
|
dataDescriptor,
|
|
1083
|
+
emptyEntry,
|
|
1083
1084
|
signal
|
|
1084
1085
|
} = options;
|
|
1085
1086
|
const {
|
|
@@ -1104,7 +1105,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
1104
1105
|
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lockFileEntry;
|
|
1105
1106
|
requestLockCurrentFileEntry();
|
|
1106
1107
|
}
|
|
1107
|
-
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || !dataDescriptor) {
|
|
1108
|
+
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
|
|
1108
1109
|
bufferedWrite = true;
|
|
1109
1110
|
zipWriter.bufferedWrites++;
|
|
1110
1111
|
if (options.createTempStream) {
|
|
@@ -1526,8 +1527,8 @@ function getHeaderInfo(options) {
|
|
|
1526
1527
|
try {
|
|
1527
1528
|
const { uid, gid, unixExtraFieldType } = options;
|
|
1528
1529
|
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
1529
|
-
const uidBytes = packUnixId(uid);
|
|
1530
|
-
const gidBytes = packUnixId(gid);
|
|
1530
|
+
const uidBytes = packUnixId(uid === UNDEFINED_VALUE ? 0 : uid);
|
|
1531
|
+
const gidBytes = packUnixId(gid === UNDEFINED_VALUE ? 0 : gid);
|
|
1531
1532
|
const payloadLength = 3 + uidBytes.length + gidBytes.length;
|
|
1532
1533
|
const extraFieldUnix = createRecordWriter(4 + payloadLength);
|
|
1533
1534
|
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_INFOZIP);
|
|
@@ -1566,12 +1567,13 @@ function getHeaderInfo(options) {
|
|
|
1566
1567
|
if (passThrough && crc32 !== UNDEFINED_VALUE) {
|
|
1567
1568
|
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
1568
1569
|
}
|
|
1569
|
-
rawExtraFieldAES
|
|
1570
|
+
setUint16(getDataView(rawExtraFieldAES), EXTRAFIELD_OFFSET_AES_COMPRESSION_METHOD, compressionMethod);
|
|
1570
1571
|
compressionMethod = COMPRESSION_METHOD_AES;
|
|
1571
1572
|
}
|
|
1572
1573
|
const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
|
|
1573
1574
|
const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
|
|
1574
|
-
|
|
1575
|
+
const maximumUsdzExtraFieldLength = options[OPTION_USDZ] ? EXTRAFIELD_USDZ_MAX_LENGTH : 0;
|
|
1576
|
+
if (extraFieldLength + maximumUsdzExtraFieldLength > MAX_16_BITS) {
|
|
1575
1577
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
1576
1578
|
}
|
|
1577
1579
|
const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
@@ -1657,18 +1659,14 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
|
|
|
1657
1659
|
}
|
|
1658
1660
|
|
|
1659
1661
|
function packUnixId(id) {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
length--;
|
|
1669
|
-
}
|
|
1670
|
-
return dataArray.subarray(0, length);
|
|
1671
|
-
}
|
|
1662
|
+
const dataArray = new Uint8Array(4);
|
|
1663
|
+
const dataView = getDataView(dataArray);
|
|
1664
|
+
dataView.setUint32(0, id, true);
|
|
1665
|
+
let length = 4;
|
|
1666
|
+
while (length > 1 && dataArray[length - 1] === 0) {
|
|
1667
|
+
length--;
|
|
1668
|
+
}
|
|
1669
|
+
return dataArray.subarray(0, length);
|
|
1672
1670
|
}
|
|
1673
1671
|
|
|
1674
1672
|
function normalizeMsdosAttributes(msdosAttributesRaw, msdosAttributes) {
|
|
@@ -1972,7 +1970,11 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
|
1972
1970
|
signatureRecord.writeUint32(DIGITAL_SIGNATURE_RECORD_SIGNATURE);
|
|
1973
1971
|
signatureRecord.writeUint16(signatureDataLength);
|
|
1974
1972
|
signatureRecord.writeBytes(signatureData);
|
|
1975
|
-
|
|
1973
|
+
const { writer } = zipWriter;
|
|
1974
|
+
if (exceedsAvailableSize(writer, getLength(signatureRecord.array))) {
|
|
1975
|
+
await writer.closeDisk();
|
|
1976
|
+
}
|
|
1977
|
+
await writeData(writer, signatureRecord.array);
|
|
1976
1978
|
return 6 + signatureDataLength;
|
|
1977
1979
|
}
|
|
1978
1980
|
return 0;
|
|
@@ -2083,7 +2085,22 @@ async function startsWithSplitZipSignature(reader) {
|
|
|
2083
2085
|
return getUint32(getDataView(signatureArray), 0) == SPLIT_ZIP_FILE_SIGNATURE;
|
|
2084
2086
|
}
|
|
2085
2087
|
|
|
2086
|
-
|
|
2088
|
+
function removeExtraFieldZip64(rawExtraField) {
|
|
2089
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
2090
|
+
let offsetExtraField = 0;
|
|
2091
|
+
while (offsetExtraField + 4 <= getLength(rawExtraField)) {
|
|
2092
|
+
const size = 4 + getUint16(rawExtraFieldView, offsetExtraField + 2);
|
|
2093
|
+
if (getUint16(rawExtraFieldView, offsetExtraField) == EXTRAFIELD_TYPE_ZIP64) {
|
|
2094
|
+
return removeExtraFieldZip64(concat(
|
|
2095
|
+
rawExtraField.subarray(0, offsetExtraField),
|
|
2096
|
+
rawExtraField.subarray(Math.min(offsetExtraField + size, getLength(rawExtraField)))));
|
|
2097
|
+
}
|
|
2098
|
+
offsetExtraField += size;
|
|
2099
|
+
}
|
|
2100
|
+
return rawExtraField;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
2087
2104
|
const { writer } = zipWriter;
|
|
2088
2105
|
const entryPositions = new Map();
|
|
2089
2106
|
if (writer.closeDisk) {
|
|
@@ -2104,9 +2121,10 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset, splitZip
|
|
|
2104
2121
|
}
|
|
2105
2122
|
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
2106
2123
|
} else {
|
|
2124
|
+
const baseOffset = zipWriter.offset;
|
|
2107
2125
|
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
2108
2126
|
entries.forEach(entry => entryPositions.set(entry, {
|
|
2109
|
-
offset:
|
|
2127
|
+
offset: baseOffset + getSourceOffset(reader, entry),
|
|
2110
2128
|
diskNumberStart: 0
|
|
2111
2129
|
}));
|
|
2112
2130
|
}
|
package/lib/zip-core-reader.js
CHANGED
package/package.json
CHANGED