@zip.js/zip.js 2.11.2 → 2.11.4
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/BENCHMARKS.md +146 -38
- package/deno.json +1 -1
- package/dist/zip-core-external.js +80 -36
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +82 -36
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +87 -41
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +89 -41
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +87 -41
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +89 -41
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +89 -41
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +82 -36
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +82 -36
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +82 -36
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +88 -40
- package/index-native.min.js +1 -1
- package/index.cjs +88 -40
- package/index.d.cts +39 -2
- package/index.d.ts +39 -2
- package/index.min.js +1 -1
- package/lib/core/io.js +7 -5
- package/lib/core/options.js +13 -0
- package/lib/core/version.js +1 -1
- package/lib/core/zip-fs.js +5 -5
- package/lib/core/zip-reader.js +20 -17
- package/lib/core/zip-writer.js +50 -13
- package/lib/zip-core-writer.js +2 -0
- package/package.json +1 -1
package/lib/core/io.js
CHANGED
|
@@ -237,11 +237,13 @@ class BlobReader extends Reader {
|
|
|
237
237
|
const reader = this;
|
|
238
238
|
const { sourceBlob, size } = reader;
|
|
239
239
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
240
|
+
if (typeof sourceBlob.stream == FUNCTION_TYPE) {
|
|
241
|
+
if (!offset && readSize >= size) {
|
|
242
|
+
return toCompatibleReadable(sourceBlob.stream());
|
|
243
|
+
}
|
|
244
|
+
if (blobSliceReliable) {
|
|
245
|
+
return toCompatibleReadable(sourceBlob.slice(offset, offset + readSize).stream());
|
|
246
|
+
}
|
|
245
247
|
}
|
|
246
248
|
return super.createReadable(options);
|
|
247
249
|
}
|
package/lib/core/options.js
CHANGED
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
/* global DOMException */
|
|
30
|
+
|
|
29
31
|
import {
|
|
30
32
|
BOOLEAN_TYPE,
|
|
31
33
|
FUNCTION_TYPE,
|
|
@@ -86,6 +88,8 @@ const STRICTNESS_TOLERANT = "tolerant";
|
|
|
86
88
|
const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
87
89
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
88
90
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
91
|
+
const ERR_ABORTED = "The operation was aborted";
|
|
92
|
+
const ABORT_ERROR_NAME = "AbortError";
|
|
89
93
|
|
|
90
94
|
export {
|
|
91
95
|
OPTION_FILENAME_ENCODING,
|
|
@@ -140,8 +144,11 @@ export {
|
|
|
140
144
|
ERR_INVALID_FUNCTION_OPTION,
|
|
141
145
|
ERR_INVALID_SIGNAL,
|
|
142
146
|
ERR_INVALID_PASSWORD_TYPE,
|
|
147
|
+
ERR_ABORTED,
|
|
148
|
+
ABORT_ERROR_NAME,
|
|
143
149
|
checkFunctionOption,
|
|
144
150
|
checkSignalOption,
|
|
151
|
+
throwIfAborted,
|
|
145
152
|
checkPasswordOption,
|
|
146
153
|
checkInteger,
|
|
147
154
|
checkIntegerOption,
|
|
@@ -162,6 +169,12 @@ function checkSignalOption(signal) {
|
|
|
162
169
|
return signal || UNDEFINED_VALUE;
|
|
163
170
|
}
|
|
164
171
|
|
|
172
|
+
function throwIfAborted(signal) {
|
|
173
|
+
if (signal && signal.aborted) {
|
|
174
|
+
throw signal.reason === UNDEFINED_VALUE ? new DOMException(ERR_ABORTED, ABORT_ERROR_NAME) : signal.reason;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
165
178
|
function checkPasswordOption(password, rawPassword) {
|
|
166
179
|
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
167
180
|
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
package/lib/core/version.js
CHANGED
package/lib/core/zip-fs.js
CHANGED
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
import {
|
|
56
56
|
Entry
|
|
57
57
|
} from "./zip-entry.js";
|
|
58
|
-
import { checkSignalOption } from "./options.js";
|
|
58
|
+
import { checkSignalOption, ERR_ABORTED, ABORT_ERROR_NAME } from "./options.js";
|
|
59
59
|
import { ProgressWatcherStream, callHandler } from "./codec-worker.js";
|
|
60
60
|
import {
|
|
61
61
|
UNDEFINED_VALUE,
|
|
@@ -92,8 +92,6 @@ const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.
|
|
|
92
92
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
93
93
|
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
94
94
|
const ERR_ABORT_EXPORT = "zipjs-abort-export";
|
|
95
|
-
const ERR_ABORTED = "The operation was aborted";
|
|
96
|
-
const ABORT_ERROR_NAME = "AbortError";
|
|
97
95
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
98
96
|
const INTERPRETED_EXTRA_FIELD_TYPES = new Set([
|
|
99
97
|
EXTRAFIELD_TYPE_ZIP64,
|
|
@@ -587,12 +585,14 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
587
585
|
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
588
586
|
options.bufferedWrite = true;
|
|
589
587
|
}
|
|
590
|
-
const
|
|
588
|
+
const children = zipEntry.getChildren({ recursive: true });
|
|
589
|
+
const entries = children.filter(child => !isImplicitDirectory(child)).map(child => {
|
|
591
590
|
const { name, entryOptions } = getChildEntryOptions(child, zipEntry, options);
|
|
592
591
|
return { name, size: child.directory ? 0 : getDeterminedSize(child, isPassThrough(child, options)), options: entryOptions };
|
|
593
592
|
});
|
|
594
593
|
const writeOrderGuaranteed = !options.bufferedWrite ||
|
|
595
|
-
(entries.every(entry => entry.options.keepOrder !== false) &&
|
|
594
|
+
(entries.every(entry => entry.options.keepOrder !== false) &&
|
|
595
|
+
children.every(child => isImplicitDirectory(child) || !child.children.length));
|
|
596
596
|
return getEntriesSize(options, entries, writeOrderGuaranteed, options.globalComment);
|
|
597
597
|
}
|
|
598
598
|
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -173,6 +173,7 @@ import {
|
|
|
173
173
|
OPTION_PREVENT_CLOSE,
|
|
174
174
|
checkFunctionOption,
|
|
175
175
|
checkSignalOption,
|
|
176
|
+
throwIfAborted,
|
|
176
177
|
checkPasswordOption,
|
|
177
178
|
toNumber
|
|
178
179
|
} from "./options.js";
|
|
@@ -668,27 +669,28 @@ class ZipReaderStream {
|
|
|
668
669
|
const { done, value } = await gen.next();
|
|
669
670
|
if (done)
|
|
670
671
|
return controller.close();
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
return readable;
|
|
678
|
-
}
|
|
672
|
+
const entryReadable = (function () {
|
|
673
|
+
const { readable, writable } = new TransformStream();
|
|
674
|
+
if (value.getData) {
|
|
675
|
+
getData();
|
|
676
|
+
return readable;
|
|
677
|
+
}
|
|
679
678
|
|
|
680
|
-
|
|
679
|
+
async function getData() {
|
|
680
|
+
try {
|
|
681
|
+
await value.getData(writable);
|
|
682
|
+
} catch (error) {
|
|
681
683
|
try {
|
|
682
|
-
await
|
|
683
|
-
} catch
|
|
684
|
-
|
|
685
|
-
await writable.abort(error);
|
|
686
|
-
} catch {
|
|
687
|
-
// ignored
|
|
688
|
-
}
|
|
684
|
+
await writable.abort(error);
|
|
685
|
+
} catch {
|
|
686
|
+
// ignored
|
|
689
687
|
}
|
|
690
688
|
}
|
|
691
|
-
}
|
|
689
|
+
}
|
|
690
|
+
})();
|
|
691
|
+
const chunk = {
|
|
692
|
+
...value,
|
|
693
|
+
readable: entryReadable
|
|
692
694
|
};
|
|
693
695
|
delete chunk.getData;
|
|
694
696
|
controller.enqueue(chunk);
|
|
@@ -880,6 +882,7 @@ class ZipEntry {
|
|
|
880
882
|
const size = compressedSize;
|
|
881
883
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
882
884
|
const signal = checkSignalOption(getOptionValue(zipEntry, options, OPTION_SIGNAL));
|
|
885
|
+
throwIfAborted(signal);
|
|
883
886
|
const checkPasswordOnly = getOptionValue(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
884
887
|
let checkOverlappingEntry = getOptionValue(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
885
888
|
const checkOverlappingEntryOnly = getOptionValue(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY_ONLY);
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -238,6 +238,7 @@ import {
|
|
|
238
238
|
ERR_INVALID_PASSWORD_TYPE,
|
|
239
239
|
checkFunctionOption,
|
|
240
240
|
checkSignalOption,
|
|
241
|
+
throwIfAborted,
|
|
241
242
|
checkPasswordOption,
|
|
242
243
|
checkInteger,
|
|
243
244
|
checkIntegerOption,
|
|
@@ -254,6 +255,7 @@ const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
|
254
255
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
255
256
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
256
257
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
258
|
+
const ERR_UNSUPPORTED_SPLIT_USDZ = "Split zip files are not supported in USDZ files";
|
|
257
259
|
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
258
260
|
const ERR_INVALID_EXTRAFIELD = "Invalid extra field (must be a Map)";
|
|
259
261
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Invalid extra field type (must be integer 0..65535)";
|
|
@@ -268,6 +270,7 @@ const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
|
268
270
|
const ERR_UNDEFINED_COMPRESSION_METHOD = "Undefined compression method";
|
|
269
271
|
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
270
272
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
273
|
+
const ERR_INVALID_READER = "Invalid reader (must be a Reader instance, a ReadableStream instance, or an object with a 'readable' property)";
|
|
271
274
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
272
275
|
const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
|
|
273
276
|
const ERR_INVALID_GID = "Invalid gid (must be integer 0..2^32-1)";
|
|
@@ -299,6 +302,9 @@ class ZipWriter {
|
|
|
299
302
|
const addSplitZipSignature =
|
|
300
303
|
availableSize > 0 && availableSize !== INFINITY_VALUE &&
|
|
301
304
|
maxSize > 0 && maxSize !== INFINITY_VALUE;
|
|
305
|
+
if (addSplitZipSignature && options[OPTION_USDZ]) {
|
|
306
|
+
throw new Error(ERR_UNSUPPORTED_SPLIT_USDZ);
|
|
307
|
+
}
|
|
302
308
|
Object.assign(this, {
|
|
303
309
|
writer,
|
|
304
310
|
addSplitZipSignature,
|
|
@@ -414,6 +420,7 @@ class ZipWriter {
|
|
|
414
420
|
}
|
|
415
421
|
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
416
422
|
Object.assign(entry, {
|
|
423
|
+
zip64Enabled: true,
|
|
417
424
|
zip64UncompressedSize,
|
|
418
425
|
zip64CompressedSize,
|
|
419
426
|
offset,
|
|
@@ -663,12 +670,14 @@ export {
|
|
|
663
670
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
664
671
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
665
672
|
ERR_UNSUPPORTED_ENCRYPTION_USDZ,
|
|
673
|
+
ERR_UNSUPPORTED_SPLIT_USDZ,
|
|
666
674
|
ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
|
|
667
675
|
ERR_UNSUPPORTED_FORMAT,
|
|
668
676
|
ERR_UNDEFINED_UNCOMPRESSED_SIZE,
|
|
669
677
|
ERR_UNDEFINED_COMPRESSION_METHOD,
|
|
670
678
|
ERR_UNDETERMINED_SIZE,
|
|
671
679
|
ERR_UNDEFINED_READER,
|
|
680
|
+
ERR_INVALID_READER,
|
|
672
681
|
ERR_ZIP_NOT_EMPTY,
|
|
673
682
|
ERR_INVALID_SIGNATURE_DATA,
|
|
674
683
|
ERR_INVALID_UID,
|
|
@@ -910,6 +919,7 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
910
919
|
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
911
920
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
912
921
|
const signal = checkSignalOption(getOptionValue(zipWriter, options, OPTION_SIGNAL));
|
|
922
|
+
throwIfAborted(signal);
|
|
913
923
|
const useUnicodeFileNames = getOptionValue(zipWriter, options, OPTION_USE_UNICODE_FILE_NAMES, true);
|
|
914
924
|
const compressionMethod = getOptionValue(zipWriter, options, PROPERTY_NAME_COMPRESSION_METHOD);
|
|
915
925
|
const registeredCodec = passThrough || compressionMethod === UNDEFINED_VALUE ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -1027,6 +1037,9 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
1027
1037
|
if (reader) {
|
|
1028
1038
|
reader = new GenericReader(reader);
|
|
1029
1039
|
await initStream(reader);
|
|
1040
|
+
if (!reader.readable && !reader.readUint8Array) {
|
|
1041
|
+
throw new Error(ERR_INVALID_READER);
|
|
1042
|
+
}
|
|
1030
1043
|
({ size: contentSize } = reader);
|
|
1031
1044
|
}
|
|
1032
1045
|
return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
|
|
@@ -1037,6 +1050,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
1037
1050
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
1038
1051
|
let maximumCompressedSize = 0;
|
|
1039
1052
|
let uncompressedSize = 0;
|
|
1053
|
+
let unknownSize = false;
|
|
1040
1054
|
if (passThrough && hasContent) {
|
|
1041
1055
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
1042
1056
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
@@ -1062,8 +1076,8 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
1062
1076
|
if (contentSize === UNDEFINED_VALUE) {
|
|
1063
1077
|
dataDescriptor = true;
|
|
1064
1078
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
1065
|
-
zip64 = true;
|
|
1066
|
-
|
|
1079
|
+
zip64 = unknownSize = true;
|
|
1080
|
+
maximumCompressedSize = MAX_32_BITS + 1;
|
|
1067
1081
|
}
|
|
1068
1082
|
} else {
|
|
1069
1083
|
options.uncompressedSize = uncompressedSize = contentSize;
|
|
@@ -1078,7 +1092,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
1078
1092
|
if (emptyEntry && !zipCrypto && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
1079
1093
|
dataDescriptor = false;
|
|
1080
1094
|
}
|
|
1081
|
-
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
1095
|
+
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
1082
1096
|
const zip64CompressedSize = zip64Enabled || maximumCompressedSize >= MAX_32_BITS;
|
|
1083
1097
|
if (zip64UncompressedSize || zip64CompressedSize) {
|
|
1084
1098
|
if (zip64 === false) {
|
|
@@ -1094,6 +1108,8 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
1094
1108
|
dataDescriptor,
|
|
1095
1109
|
emptyEntry,
|
|
1096
1110
|
zip64,
|
|
1111
|
+
zip64Enabled,
|
|
1112
|
+
unknownSize,
|
|
1097
1113
|
zip64UncompressedSize,
|
|
1098
1114
|
zip64CompressedSize,
|
|
1099
1115
|
uncompressedSize,
|
|
@@ -1167,7 +1183,7 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1167
1183
|
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
1168
1184
|
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
1169
1185
|
}
|
|
1170
|
-
const directoryDataLength = createDirectoryRecords(files);
|
|
1186
|
+
const { directoryDataLength, zip64Entries } = createDirectoryRecords(files);
|
|
1171
1187
|
let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
|
|
1172
1188
|
if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
|
|
1173
1189
|
if (zip64 === false) {
|
|
@@ -1175,6 +1191,8 @@ async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comm
|
|
|
1175
1191
|
} else {
|
|
1176
1192
|
zip64 = true;
|
|
1177
1193
|
}
|
|
1194
|
+
} else if (zip64 === UNDEFINED_VALUE && zip64Entries) {
|
|
1195
|
+
zip64 = true;
|
|
1178
1196
|
}
|
|
1179
1197
|
return offset - initialOffset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
1180
1198
|
}
|
|
@@ -1367,6 +1385,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
1367
1385
|
rawPassword,
|
|
1368
1386
|
level,
|
|
1369
1387
|
zip64,
|
|
1388
|
+
zip64Enabled,
|
|
1370
1389
|
zip64UncompressedSize,
|
|
1371
1390
|
zip64CompressedSize,
|
|
1372
1391
|
zipCrypto,
|
|
@@ -1407,6 +1426,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
1407
1426
|
lockFileEntry,
|
|
1408
1427
|
versionMadeBy,
|
|
1409
1428
|
zip64,
|
|
1429
|
+
zip64Enabled,
|
|
1410
1430
|
directory: Boolean(directory),
|
|
1411
1431
|
executable: Boolean(executable),
|
|
1412
1432
|
filenameUTF8: true,
|
|
@@ -1550,13 +1570,14 @@ function getHeaderInfo(options) {
|
|
|
1550
1570
|
zip64UncompressedSize,
|
|
1551
1571
|
zip64CompressedSize,
|
|
1552
1572
|
uncompressedSize,
|
|
1573
|
+
unknownSize,
|
|
1553
1574
|
crc32
|
|
1554
1575
|
} = options;
|
|
1555
1576
|
let { version, compressionMethod } = options;
|
|
1556
1577
|
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
1557
1578
|
let rawLocalExtraFieldZip64;
|
|
1558
1579
|
const uncompressedFile = passThrough || !compressed;
|
|
1559
|
-
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
1580
|
+
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || (uncompressedFile && !unknownSize)));
|
|
1560
1581
|
const writeLocalExtraFieldZip64 = zip64ExtraFieldComplete || (zip64 && dataDescriptor && (zip64UncompressedSize || zip64CompressedSize));
|
|
1561
1582
|
if (zip64 && (zip64UncompressedSize || zip64CompressedSize)) {
|
|
1562
1583
|
const length = 4 + 16;
|
|
@@ -1690,6 +1711,10 @@ function getHeaderInfo(options) {
|
|
|
1690
1711
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
1691
1712
|
}
|
|
1692
1713
|
const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
1714
|
+
const clampedLastModDate = dosLastModDate < MIN_DATE ? MIN_DATE : dosLastModDate > MAX_DATE ? MAX_DATE : dosLastModDate;
|
|
1715
|
+
const storedLastModDate = getLength(rawExtraFieldExtendedTimestamp) ?
|
|
1716
|
+
new Date(getTimeUnix(lastModDate) * 1000) :
|
|
1717
|
+
getLength(rawExtraFieldNTFS) ? lastModDate : clampedLastModDate;
|
|
1693
1718
|
const {
|
|
1694
1719
|
headerArray,
|
|
1695
1720
|
headerView,
|
|
@@ -1699,7 +1724,7 @@ function getHeaderInfo(options) {
|
|
|
1699
1724
|
bitFlag: getBitFlag(level, useUnicodeFileNames, dataDescriptor, encrypted, compressionMethod),
|
|
1700
1725
|
compressionMethod,
|
|
1701
1726
|
uncompressedSize,
|
|
1702
|
-
lastModDate:
|
|
1727
|
+
lastModDate: clampedLastModDate,
|
|
1703
1728
|
rawLastModDate: rawLastModDateOption,
|
|
1704
1729
|
rawFilename,
|
|
1705
1730
|
zip64CompressedSize,
|
|
@@ -1734,7 +1759,7 @@ function getHeaderInfo(options) {
|
|
|
1734
1759
|
localHeaderView,
|
|
1735
1760
|
headerArray,
|
|
1736
1761
|
headerView,
|
|
1737
|
-
lastModDate,
|
|
1762
|
+
lastModDate: storedLastModDate,
|
|
1738
1763
|
rawLastModDate,
|
|
1739
1764
|
encrypted,
|
|
1740
1765
|
compressed,
|
|
@@ -1906,14 +1931,15 @@ function updateLocalHeader({
|
|
|
1906
1931
|
|
|
1907
1932
|
|
|
1908
1933
|
async function closeFile(zipWriter, comment, options) {
|
|
1909
|
-
const directoryDataLength = createDirectoryRecords(zipWriter.fileEntries);
|
|
1934
|
+
const { directoryDataLength, zip64Entries } = createDirectoryRecords(zipWriter.fileEntries);
|
|
1910
1935
|
const { directoryStart, directoryEnd, directoryArray } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
1911
1936
|
const signatureLength = await writeDigitalSignatureRecord(zipWriter, directoryArray, options);
|
|
1912
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength });
|
|
1937
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryEnd, directoryDataLength, signatureLength, zip64Entries });
|
|
1913
1938
|
}
|
|
1914
1939
|
|
|
1915
1940
|
function createDirectoryRecords(files) {
|
|
1916
1941
|
let directoryDataLength = 0;
|
|
1942
|
+
let zip64Entries = false;
|
|
1917
1943
|
for (const [, fileEntry] of files) {
|
|
1918
1944
|
const {
|
|
1919
1945
|
rawFilename,
|
|
@@ -1926,11 +1952,20 @@ function createDirectoryRecords(files) {
|
|
|
1926
1952
|
extendedTimestamp,
|
|
1927
1953
|
extraFieldExtendedTimestampFlag,
|
|
1928
1954
|
lastModDate,
|
|
1929
|
-
|
|
1930
|
-
zip64CompressedSize,
|
|
1955
|
+
zip64Enabled,
|
|
1931
1956
|
uncompressedSize,
|
|
1932
1957
|
compressedSize
|
|
1933
1958
|
} = fileEntry;
|
|
1959
|
+
let { zip64UncompressedSize, zip64CompressedSize } = fileEntry;
|
|
1960
|
+
if (!zip64Enabled) {
|
|
1961
|
+
if (zip64UncompressedSize && uncompressedSize < MAX_32_BITS) {
|
|
1962
|
+
zip64UncompressedSize = fileEntry.zip64UncompressedSize = false;
|
|
1963
|
+
}
|
|
1964
|
+
if (zip64CompressedSize && compressedSize < MAX_32_BITS) {
|
|
1965
|
+
zip64CompressedSize = fileEntry.zip64CompressedSize = false;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
zip64Entries = zip64Entries || zip64UncompressedSize || zip64CompressedSize;
|
|
1934
1969
|
const zip64Offset = fileEntry.offset >= MAX_32_BITS;
|
|
1935
1970
|
const zip64DiskNumberStart = fileEntry.diskNumberStart >= MAX_16_BITS;
|
|
1936
1971
|
let rawExtraFieldZip64;
|
|
@@ -1984,7 +2019,7 @@ function createDirectoryRecords(files) {
|
|
|
1984
2019
|
}
|
|
1985
2020
|
directoryDataLength += CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
1986
2021
|
}
|
|
1987
|
-
return directoryDataLength;
|
|
2022
|
+
return { directoryDataLength, zip64Entries };
|
|
1988
2023
|
}
|
|
1989
2024
|
|
|
1990
2025
|
async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
@@ -2104,7 +2139,7 @@ async function writeDigitalSignatureRecord(zipWriter, directoryArray, options) {
|
|
|
2104
2139
|
|
|
2105
2140
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
2106
2141
|
const { writer } = zipWriter;
|
|
2107
|
-
const { directoryStart, directoryEnd, signatureLength } = cdInfo;
|
|
2142
|
+
const { directoryStart, directoryEnd, signatureLength, zip64Entries } = cdInfo;
|
|
2108
2143
|
let { directoryDataLength } = cdInfo;
|
|
2109
2144
|
let fileEntriesLength = zipWriter.fileEntries.size;
|
|
2110
2145
|
let diskNumber = directoryStart.diskNumber;
|
|
@@ -2124,6 +2159,8 @@ async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
|
2124
2159
|
} else {
|
|
2125
2160
|
zip64 = true;
|
|
2126
2161
|
}
|
|
2162
|
+
} else if (zip64 === UNDEFINED_VALUE && zip64Entries) {
|
|
2163
|
+
zip64 = true;
|
|
2127
2164
|
}
|
|
2128
2165
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
2129
2166
|
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
package/lib/zip-core-writer.js
CHANGED
|
@@ -45,12 +45,14 @@ export {
|
|
|
45
45
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
46
46
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
47
47
|
ERR_UNSUPPORTED_ENCRYPTION_USDZ,
|
|
48
|
+
ERR_UNSUPPORTED_SPLIT_USDZ,
|
|
48
49
|
ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
|
|
49
50
|
ERR_UNSUPPORTED_FORMAT,
|
|
50
51
|
ERR_UNDEFINED_UNCOMPRESSED_SIZE,
|
|
51
52
|
ERR_UNDEFINED_COMPRESSION_METHOD,
|
|
52
53
|
ERR_UNDETERMINED_SIZE,
|
|
53
54
|
ERR_UNDEFINED_READER,
|
|
55
|
+
ERR_INVALID_READER,
|
|
54
56
|
ERR_ZIP_NOT_EMPTY,
|
|
55
57
|
ERR_INVALID_SIGNATURE_DATA,
|
|
56
58
|
ERR_INVALID_UID,
|
package/package.json
CHANGED