@zip.js/zip.js 2.8.51 → 2.8.53
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/README.md +8 -3
- package/deno.json +1 -1
- package/dist/zip-core-external.js +241 -95
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +243 -94
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +564 -199
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +551 -194
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +564 -199
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +567 -198
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +567 -198
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +243 -94
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +243 -94
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +243 -94
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +1 -1
- package/index-native.cjs +567 -198
- package/index-native.min.js +1 -1
- package/index.cjs +567 -198
- package/index.d.cts +551 -45
- package/index.d.ts +551 -45
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +13 -4
- package/lib/core/codec-worker.js +2 -0
- package/lib/core/constants.js +9 -0
- package/lib/core/io.js +43 -4
- package/lib/core/options.js +2 -0
- package/lib/core/util/compatible-streams.js +3 -8
- package/lib/core/zip-entry.js +16 -0
- package/lib/core/zip-fs.js +236 -107
- package/lib/core/zip-reader.js +106 -40
- package/lib/core/zip-writer.js +171 -41
- package/lib/zip-core-writer.js +3 -0
- package/package.json +9 -7
package/lib/core/zip-writer.js
CHANGED
|
@@ -120,12 +120,17 @@ import {
|
|
|
120
120
|
FILE_ATTR_MSDOS_SYSTEM_MASK,
|
|
121
121
|
FILE_ATTR_MSDOS_ARCHIVE_MASK,
|
|
122
122
|
FILE_ATTR_UNIX_TYPE_DIR,
|
|
123
|
+
FILE_ATTR_UNIX_TYPE_FILE,
|
|
124
|
+
FILE_ATTR_UNIX_TYPE_MASK,
|
|
125
|
+
FILE_ATTR_UNIX_TYPE_SYMLINK,
|
|
123
126
|
FILE_ATTR_UNIX_EXECUTABLE_MASK,
|
|
124
127
|
FILE_ATTR_UNIX_DEFAULT_MASK,
|
|
125
128
|
FILE_ATTR_UNIX_SETUID_MASK,
|
|
126
129
|
FILE_ATTR_UNIX_SETGID_MASK,
|
|
127
130
|
FILE_ATTR_UNIX_STICKY_MASK,
|
|
128
131
|
VERSION_DEFLATE,
|
|
132
|
+
VERSION_MADE_BY_MSDOS,
|
|
133
|
+
VERSION_MADE_BY_UNIX,
|
|
129
134
|
VERSION_ZIP64,
|
|
130
135
|
VERSION_AES,
|
|
131
136
|
DIRECTORY_SIGNATURE,
|
|
@@ -154,17 +159,21 @@ import {
|
|
|
154
159
|
import {
|
|
155
160
|
initStream,
|
|
156
161
|
GenericWriter,
|
|
157
|
-
GenericReader
|
|
162
|
+
GenericReader,
|
|
163
|
+
BlobReader,
|
|
164
|
+
ownsWritable
|
|
158
165
|
} from "./io.js";
|
|
159
166
|
import { encodeText } from "./util/encode-text.js";
|
|
160
167
|
import { getDataView } from "./util/array.js";
|
|
161
|
-
import { toCompatibleReadable } from "./util/compatible-streams.js";
|
|
168
|
+
import { toCompatibleReadable, streamToBlob } from "./util/compatible-streams.js";
|
|
162
169
|
import {
|
|
163
170
|
PROPERTY_NAME_LAST_MODIFICATION_DATE,
|
|
164
171
|
PROPERTY_NAME_LAST_ACCESS_DATE,
|
|
165
172
|
PROPERTY_NAME_CREATION_DATE,
|
|
166
173
|
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES,
|
|
167
174
|
PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES,
|
|
175
|
+
PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES,
|
|
176
|
+
PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES,
|
|
168
177
|
PROPERTY_NAME_MS_DOS_COMPATIBLE,
|
|
169
178
|
PROPERTY_NAME_ZIP64,
|
|
170
179
|
PROPERTY_NAME_ENCRYPTED,
|
|
@@ -220,11 +229,13 @@ import {
|
|
|
220
229
|
|
|
221
230
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
222
231
|
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
232
|
+
const ERR_INVALID_COMMENT_TYPE = "Invalid zip file comment (must be a Uint8Array)";
|
|
223
233
|
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
224
234
|
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
225
235
|
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
226
236
|
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
227
237
|
const ERR_UNSUPPORTED_ENCRYPTION_USDZ = "Encryption is not supported in USDZ files";
|
|
238
|
+
const ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH = "Encryption is not supported when the 'passThrough' option is set";
|
|
228
239
|
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
229
240
|
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
230
241
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
@@ -234,6 +245,7 @@ const MIN_NTFS_TIME = BigInt(0);
|
|
|
234
245
|
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
235
246
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
236
247
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
248
|
+
const ERR_UNDETERMINED_SIZE = "Undetermined size";
|
|
237
249
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
238
250
|
const ERR_ZIP_NOT_EMPTY = "Zip file not empty";
|
|
239
251
|
const ERR_INVALID_UID = "Invalid uid (must be integer 0..2^32-1)";
|
|
@@ -286,6 +298,10 @@ class ZipWriter {
|
|
|
286
298
|
}
|
|
287
299
|
reader = new GenericReader(reader);
|
|
288
300
|
await initStream(reader);
|
|
301
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
302
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
303
|
+
await initStream(reader);
|
|
304
|
+
}
|
|
289
305
|
const { ZipReader } = await import("./zip-reader.js");
|
|
290
306
|
const zipReader = new ZipReader(reader.readable);
|
|
291
307
|
const entries = await zipReader.getEntries();
|
|
@@ -434,6 +450,9 @@ class ZipWriter {
|
|
|
434
450
|
const zipWriter = this;
|
|
435
451
|
const { pendingAddFileCalls, writer } = this;
|
|
436
452
|
const { writable } = writer;
|
|
453
|
+
if (!(comment instanceof Uint8Array)) {
|
|
454
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
455
|
+
}
|
|
437
456
|
if (getLength(comment) > MAX_16_BITS) {
|
|
438
457
|
throw new Error(ERR_INVALID_COMMENT);
|
|
439
458
|
}
|
|
@@ -441,7 +460,7 @@ class ZipWriter {
|
|
|
441
460
|
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
442
461
|
}
|
|
443
462
|
await closeFile(zipWriter, comment, options);
|
|
444
|
-
const preventClose = getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
463
|
+
const preventClose = !ownsWritable(writer) && getOptionValue(zipWriter, options, OPTION_PREVENT_CLOSE);
|
|
445
464
|
if (!preventClose) {
|
|
446
465
|
await writable.getWriter().close();
|
|
447
466
|
}
|
|
@@ -514,8 +533,10 @@ function watchAddFileCall(zipWriterStream, promiseAddFile, onerror) {
|
|
|
514
533
|
export {
|
|
515
534
|
ZipWriter,
|
|
516
535
|
ZipWriterStream,
|
|
536
|
+
getEntriesSize,
|
|
517
537
|
ERR_DUPLICATED_NAME,
|
|
518
538
|
ERR_INVALID_COMMENT,
|
|
539
|
+
ERR_INVALID_COMMENT_TYPE,
|
|
519
540
|
ERR_INVALID_ENTRY_NAME,
|
|
520
541
|
ERR_INVALID_ENTRY_COMMENT,
|
|
521
542
|
ERR_INVALID_VERSION,
|
|
@@ -523,8 +544,10 @@ export {
|
|
|
523
544
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
524
545
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
525
546
|
ERR_UNSUPPORTED_ENCRYPTION_USDZ,
|
|
547
|
+
ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
|
|
526
548
|
ERR_UNSUPPORTED_FORMAT,
|
|
527
549
|
ERR_UNDEFINED_UNCOMPRESSED_SIZE,
|
|
550
|
+
ERR_UNDETERMINED_SIZE,
|
|
528
551
|
ERR_UNDEFINED_READER,
|
|
529
552
|
ERR_ZIP_NOT_EMPTY,
|
|
530
553
|
ERR_INVALID_SIGNATURE_DATA,
|
|
@@ -559,8 +582,6 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
559
582
|
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
560
583
|
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
561
584
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
562
|
-
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
563
|
-
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
564
585
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
565
586
|
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
566
587
|
offset: zipWriter.offset - diskOffset,
|
|
@@ -574,14 +595,20 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
574
595
|
zipWriter.files.delete(name);
|
|
575
596
|
throw error;
|
|
576
597
|
}
|
|
577
|
-
Object.assign(fileEntry, {
|
|
598
|
+
Object.assign(fileEntry, {
|
|
599
|
+
name,
|
|
600
|
+
comment,
|
|
601
|
+
extraField,
|
|
602
|
+
[PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES]: fileEntry.internalFileAttributes,
|
|
603
|
+
[PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES]: fileEntry.externalFileAttributes
|
|
604
|
+
});
|
|
578
605
|
return new Entry(fileEntry);
|
|
579
606
|
}
|
|
580
607
|
|
|
581
608
|
function resolveAttributes(zipWriter, name, options) {
|
|
582
609
|
name = name.trim();
|
|
583
610
|
let msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE);
|
|
584
|
-
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ?
|
|
611
|
+
let versionMadeBy = getOptionValue(zipWriter, options, PROPERTY_NAME_VERSION_MADE_BY, msDosCompatible ? VERSION_MADE_BY_MSDOS : VERSION_MADE_BY_UNIX);
|
|
585
612
|
const executable = getOptionValue(zipWriter, options, PROPERTY_NAME_EXECUTABLE);
|
|
586
613
|
const uid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_UID);
|
|
587
614
|
const gid = getNumberOptionValue(zipWriter, options, PROPERTY_NAME_GID);
|
|
@@ -615,7 +642,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
615
642
|
const hasMsDosProvided = msdosAttributesRaw !== UNDEFINED_VALUE || msdosAttributes !== UNDEFINED_VALUE;
|
|
616
643
|
if (hasUnixMetadata) {
|
|
617
644
|
msDosCompatible = false;
|
|
618
|
-
versionMadeBy = (versionMadeBy &
|
|
645
|
+
versionMadeBy = (versionMadeBy & MAX_8_BITS) | VERSION_MADE_BY_UNIX;
|
|
619
646
|
} else if (hasMsDosProvided) {
|
|
620
647
|
msDosCompatible = true;
|
|
621
648
|
versionMadeBy = (versionMadeBy & MAX_8_BITS);
|
|
@@ -629,7 +656,7 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
629
656
|
if (versionMadeBy > MAX_16_BITS) {
|
|
630
657
|
throw new Error(ERR_INVALID_VERSION);
|
|
631
658
|
}
|
|
632
|
-
let externalFileAttributes =
|
|
659
|
+
let externalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_EXTERNAL_FILE_ATTRIBUTES);
|
|
633
660
|
const externalFileAttributesProvided = externalFileAttributes !== UNDEFINED_VALUE;
|
|
634
661
|
if (!externalFileAttributesProvided) {
|
|
635
662
|
externalFileAttributes = 0;
|
|
@@ -655,11 +682,10 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
655
682
|
externalFileAttributes = FILE_ATTR_UNIX_DEFAULT_MASK << 16;
|
|
656
683
|
}
|
|
657
684
|
}
|
|
658
|
-
let unixExternalUpper;
|
|
659
685
|
if (!msDosCompatible) {
|
|
660
686
|
const unixModeProvided = unixMode !== UNDEFINED_VALUE || Boolean(setuid || setgid || sticky);
|
|
661
|
-
|
|
662
|
-
unixMode = unixMode === UNDEFINED_VALUE ?
|
|
687
|
+
const defaultUnixMode = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
688
|
+
unixMode = unixMode === UNDEFINED_VALUE ? defaultUnixMode : (unixMode & MAX_16_BITS);
|
|
663
689
|
if (setuid) {
|
|
664
690
|
unixMode |= FILE_ATTR_UNIX_SETUID_MASK;
|
|
665
691
|
} else {
|
|
@@ -677,7 +703,9 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
677
703
|
}
|
|
678
704
|
if (!externalFileAttributesProvided || unixModeProvided) {
|
|
679
705
|
if (directory) {
|
|
680
|
-
unixMode
|
|
706
|
+
unixMode = (unixMode & ~FILE_ATTR_UNIX_TYPE_MASK) | FILE_ATTR_UNIX_TYPE_DIR;
|
|
707
|
+
} else if (!(unixMode & FILE_ATTR_UNIX_TYPE_MASK)) {
|
|
708
|
+
unixMode |= FILE_ATTR_UNIX_TYPE_FILE;
|
|
681
709
|
}
|
|
682
710
|
externalFileAttributes = ((unixMode & MAX_16_BITS) << 16) | (externalFileAttributes & MAX_16_BITS);
|
|
683
711
|
}
|
|
@@ -686,17 +714,20 @@ function resolveAttributes(zipWriter, name, options) {
|
|
|
686
714
|
if (hasMsDosProvided) {
|
|
687
715
|
externalFileAttributes = (externalFileAttributes & MAX_32_BITS) | (msdosAttributesRaw & MAX_8_BITS);
|
|
688
716
|
}
|
|
717
|
+
const unixExternalUpper = (externalFileAttributes >> 16) & MAX_16_BITS;
|
|
718
|
+
const symlink = unixMode !== UNDEFINED_VALUE && ((unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK);
|
|
689
719
|
return {
|
|
690
720
|
name,
|
|
691
721
|
resolvedOptions: {
|
|
692
722
|
versionMadeBy,
|
|
693
|
-
msDosCompatible,
|
|
723
|
+
msDosCompatible: Boolean(msDosCompatible),
|
|
694
724
|
externalFileAttributes,
|
|
695
725
|
unixExternalUpper,
|
|
696
726
|
uid,
|
|
697
727
|
gid,
|
|
698
728
|
unixMode,
|
|
699
729
|
unixExtraFieldType,
|
|
730
|
+
symlink,
|
|
700
731
|
setuid,
|
|
701
732
|
setgid,
|
|
702
733
|
sticky,
|
|
@@ -730,15 +761,12 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
730
761
|
const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
731
762
|
const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
732
763
|
const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
733
|
-
const internalFileAttributes =
|
|
764
|
+
const internalFileAttributes = getAliasedOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTES, PROPERTY_NAME_DEPRECATED_INTERNAL_FILE_ATTRIBUTES, 0);
|
|
734
765
|
const passThrough = getOptionValue(zipWriter, options, OPTION_PASS_THROUGH);
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
740
|
-
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
741
|
-
}
|
|
766
|
+
const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
767
|
+
const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
768
|
+
if ((password && typeof password != STRING_TYPE) || (rawPassword && !(rawPassword instanceof Uint8Array))) {
|
|
769
|
+
throw new Error(ERR_INVALID_PASSWORD_TYPE);
|
|
742
770
|
}
|
|
743
771
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
744
772
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
@@ -851,14 +879,24 @@ function serializeExtraField(extraField) {
|
|
|
851
879
|
}
|
|
852
880
|
|
|
853
881
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
882
|
+
if (metadata.passThrough && !reader && !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY)) {
|
|
883
|
+
throw new Error(ERR_UNDEFINED_READER);
|
|
884
|
+
}
|
|
885
|
+
let contentSize;
|
|
886
|
+
if (reader) {
|
|
887
|
+
reader = new GenericReader(reader);
|
|
888
|
+
await initStream(reader);
|
|
889
|
+
({ size: contentSize } = reader);
|
|
890
|
+
}
|
|
891
|
+
return Object.assign({ reader }, resolveEntrySizes(zipWriter, Boolean(reader), contentSize, metadata, options));
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options) {
|
|
854
895
|
const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
855
896
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
856
897
|
let maximumCompressedSize = 0;
|
|
857
898
|
let uncompressedSize = 0;
|
|
858
|
-
if (passThrough) {
|
|
859
|
-
if (!reader) {
|
|
860
|
-
throw new Error(ERR_UNDEFINED_READER);
|
|
861
|
-
}
|
|
899
|
+
if (passThrough && hasContent) {
|
|
862
900
|
uncompressedSize = options[PROPERTY_NAME_UNCOMPRESSED_SIZE];
|
|
863
901
|
if (uncompressedSize === UNDEFINED_VALUE) {
|
|
864
902
|
throw new Error(ERR_UNDEFINED_UNCOMPRESSED_SIZE);
|
|
@@ -866,29 +904,30 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
866
904
|
}
|
|
867
905
|
const zip64Enabled = zip64 === true;
|
|
868
906
|
const encrypted = getOptionValue(zipWriter, options, PROPERTY_NAME_ENCRYPTED);
|
|
869
|
-
|
|
870
|
-
|
|
907
|
+
if (hasContent && passThrough && !encrypted && getLength(password, rawPassword)) {
|
|
908
|
+
throw new Error(ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH);
|
|
909
|
+
}
|
|
910
|
+
const encryptedEntry = hasContent && (Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword))) || (passThrough && encrypted));
|
|
911
|
+
if (!hasContent) {
|
|
871
912
|
level = 0;
|
|
872
913
|
compressionMethod = COMPRESSION_METHOD_STORE;
|
|
873
914
|
}
|
|
874
915
|
const encryptionOverhead = encryptedEntry ? (zipCrypto ? 12 : 16 + encryptionStrength * 4) : 0;
|
|
875
|
-
if (
|
|
876
|
-
reader = new GenericReader(reader);
|
|
877
|
-
await initStream(reader);
|
|
916
|
+
if (hasContent) {
|
|
878
917
|
if (!passThrough) {
|
|
879
|
-
if (
|
|
918
|
+
if (contentSize === UNDEFINED_VALUE) {
|
|
880
919
|
dataDescriptor = true;
|
|
881
920
|
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
882
921
|
zip64 = true;
|
|
883
922
|
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
884
923
|
}
|
|
885
924
|
} else {
|
|
886
|
-
options.uncompressedSize = uncompressedSize =
|
|
887
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
925
|
+
options.uncompressedSize = uncompressedSize = contentSize;
|
|
926
|
+
maximumCompressedSize = (isCompressed(compressionMethod, level) ? getMaximumCompressedSize(uncompressedSize) : uncompressedSize) + encryptionOverhead;
|
|
888
927
|
}
|
|
889
928
|
} else {
|
|
890
929
|
options.uncompressedSize = uncompressedSize;
|
|
891
|
-
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize) + encryptionOverhead;
|
|
930
|
+
maximumCompressedSize = contentSize === UNDEFINED_VALUE ? getMaximumCompressedSize(uncompressedSize) + encryptionOverhead : contentSize;
|
|
892
931
|
}
|
|
893
932
|
}
|
|
894
933
|
const zip64UncompressedSize = zip64Enabled || uncompressedSize >= MAX_32_BITS;
|
|
@@ -902,7 +941,7 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
902
941
|
}
|
|
903
942
|
zip64 = zip64 || false;
|
|
904
943
|
return {
|
|
905
|
-
|
|
944
|
+
maximumCompressedSize,
|
|
906
945
|
resolvedOptions: {
|
|
907
946
|
dataDescriptor,
|
|
908
947
|
zip64,
|
|
@@ -916,6 +955,81 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
916
955
|
};
|
|
917
956
|
}
|
|
918
957
|
|
|
958
|
+
async function getEntriesSize(writerOptions, entries, writeOrderGuaranteed, comment) {
|
|
959
|
+
const zipWriter = { options: writerOptions, config: getConfiguration() };
|
|
960
|
+
if (writerOptions[OPTION_SIGN_CENTRAL_DIRECTORY]) {
|
|
961
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
962
|
+
}
|
|
963
|
+
if (comment !== UNDEFINED_VALUE && !(comment instanceof Uint8Array)) {
|
|
964
|
+
throw new Error(ERR_INVALID_COMMENT_TYPE);
|
|
965
|
+
}
|
|
966
|
+
const commentLength = getLength(comment);
|
|
967
|
+
if (commentLength > MAX_16_BITS) {
|
|
968
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
969
|
+
}
|
|
970
|
+
const usdz = writerOptions[OPTION_USDZ];
|
|
971
|
+
const files = new Map();
|
|
972
|
+
let layoutDependsOnWriteOrder = Boolean(usdz);
|
|
973
|
+
let offset = 0;
|
|
974
|
+
for (const entry of entries) {
|
|
975
|
+
let { name } = entry;
|
|
976
|
+
const { size } = entry;
|
|
977
|
+
const options = Object.assign({}, entry.options);
|
|
978
|
+
name = name.trim();
|
|
979
|
+
if (getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY) && !name.endsWith(DIRECTORY_SIGNATURE)) {
|
|
980
|
+
name += DIRECTORY_SIGNATURE;
|
|
981
|
+
}
|
|
982
|
+
const attributesInfo = resolveAttributes(zipWriter, name, options);
|
|
983
|
+
({ name } = attributesInfo);
|
|
984
|
+
const { resolvedOptions: metadata } = resolveMetadata(zipWriter, name, options);
|
|
985
|
+
if (metadata.level != 0 && metadata.compressionMethod === UNDEFINED_VALUE &&
|
|
986
|
+
!metadata.passThrough && !(await supportsDeflate(zipWriter.config))) {
|
|
987
|
+
metadata.level = 0;
|
|
988
|
+
}
|
|
989
|
+
const hasContent = !getOptionValue(zipWriter, options, PROPERTY_NAME_DIRECTORY);
|
|
990
|
+
if (hasContent && size === UNDEFINED_VALUE) {
|
|
991
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
992
|
+
}
|
|
993
|
+
const { maximumCompressedSize, resolvedOptions: sizes } = resolveEntrySizes(zipWriter, hasContent, size, metadata, options);
|
|
994
|
+
if (hasContent && !metadata.passThrough && isCompressed(sizes.compressionMethod, sizes.level)) {
|
|
995
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
996
|
+
}
|
|
997
|
+
const entryOptions = Object.assign({}, options, attributesInfo.resolvedOptions, metadata, sizes);
|
|
998
|
+
const headerInfo = getHeaderInfo(entryOptions);
|
|
999
|
+
const dataDescriptorInfo = getDataDescriptorInfo(entryOptions);
|
|
1000
|
+
const entryInfo = {
|
|
1001
|
+
headerInfo,
|
|
1002
|
+
metadataSize: getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray)
|
|
1003
|
+
};
|
|
1004
|
+
if (usdz) {
|
|
1005
|
+
appendExtraFieldUSDZ(entryInfo, offset);
|
|
1006
|
+
}
|
|
1007
|
+
const compressedSize = hasContent ? maximumCompressedSize : 0;
|
|
1008
|
+
if (offset >= MAX_32_BITS) {
|
|
1009
|
+
layoutDependsOnWriteOrder = true;
|
|
1010
|
+
}
|
|
1011
|
+
files.set(name, Object.assign({}, entryOptions, headerInfo, {
|
|
1012
|
+
offset,
|
|
1013
|
+
diskNumberStart: 0,
|
|
1014
|
+
compressedSize
|
|
1015
|
+
}));
|
|
1016
|
+
offset += entryInfo.metadataSize + compressedSize;
|
|
1017
|
+
}
|
|
1018
|
+
if (layoutDependsOnWriteOrder && !writeOrderGuaranteed) {
|
|
1019
|
+
throw new Error(ERR_UNDETERMINED_SIZE);
|
|
1020
|
+
}
|
|
1021
|
+
const directoryDataLength = createDirectoryRecords(files);
|
|
1022
|
+
let zip64 = getOptionValue(zipWriter, writerOptions, PROPERTY_NAME_ZIP64);
|
|
1023
|
+
if (offset >= MAX_32_BITS || directoryDataLength >= MAX_32_BITS || files.size >= MAX_16_BITS) {
|
|
1024
|
+
if (zip64 === false) {
|
|
1025
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
1026
|
+
} else {
|
|
1027
|
+
zip64 = true;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
return offset + directoryDataLength + commentLength + (zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
1031
|
+
}
|
|
1032
|
+
|
|
919
1033
|
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
920
1034
|
const {
|
|
921
1035
|
files,
|
|
@@ -1130,6 +1244,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1130
1244
|
uid,
|
|
1131
1245
|
gid,
|
|
1132
1246
|
unixMode,
|
|
1247
|
+
symlink,
|
|
1133
1248
|
setuid,
|
|
1134
1249
|
setgid,
|
|
1135
1250
|
sticky,
|
|
@@ -1166,6 +1281,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1166
1281
|
uid,
|
|
1167
1282
|
gid,
|
|
1168
1283
|
unixMode,
|
|
1284
|
+
symlink: Boolean(symlink),
|
|
1169
1285
|
setuid,
|
|
1170
1286
|
setgid,
|
|
1171
1287
|
sticky,
|
|
@@ -1246,8 +1362,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
1246
1362
|
rawLastModDate,
|
|
1247
1363
|
creationDate,
|
|
1248
1364
|
lastAccessDate,
|
|
1249
|
-
encrypted,
|
|
1250
|
-
zipCrypto,
|
|
1365
|
+
encrypted: Boolean(encrypted),
|
|
1366
|
+
zipCrypto: Boolean(zipCrypto),
|
|
1251
1367
|
size: metadataSize + compressedSize,
|
|
1252
1368
|
compressionMethod,
|
|
1253
1369
|
version,
|
|
@@ -1287,9 +1403,7 @@ function getHeaderInfo(options) {
|
|
|
1287
1403
|
crc32
|
|
1288
1404
|
} = options;
|
|
1289
1405
|
let { version, compressionMethod } = options;
|
|
1290
|
-
const compressed = !directory && (compressionMethod
|
|
1291
|
-
? (level === UNDEFINED_VALUE || level > 0)
|
|
1292
|
-
: compressionMethod !== COMPRESSION_METHOD_STORE);
|
|
1406
|
+
const compressed = !directory && isCompressed(compressionMethod, level);
|
|
1293
1407
|
let rawLocalExtraFieldZip64;
|
|
1294
1408
|
const uncompressedFile = passThrough || !compressed;
|
|
1295
1409
|
const zip64ExtraFieldComplete = zip64 && (options.bufferedWrite || !dataDescriptor || ((!zip64UncompressedSize && !zip64CompressedSize) || uncompressedFile));
|
|
@@ -1976,6 +2090,16 @@ function getOptionValue(zipWriter, options, name, defaultValue) {
|
|
|
1976
2090
|
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
1977
2091
|
}
|
|
1978
2092
|
|
|
2093
|
+
function getAliasedOptionValue(zipWriter, options, name, deprecatedName, defaultValue) {
|
|
2094
|
+
const value = getAliasedValue(options, name, deprecatedName);
|
|
2095
|
+
const result = value === UNDEFINED_VALUE ? getAliasedValue(zipWriter.options, name, deprecatedName) : value;
|
|
2096
|
+
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
function getAliasedValue(options, name, deprecatedName) {
|
|
2100
|
+
return options[name] === UNDEFINED_VALUE ? options[deprecatedName] : options[name];
|
|
2101
|
+
}
|
|
2102
|
+
|
|
1979
2103
|
function getNumberOptionValue(zipWriter, options, name, defaultValue) {
|
|
1980
2104
|
return toNumber(getOptionValue(zipWriter, options, name, defaultValue));
|
|
1981
2105
|
}
|
|
@@ -1988,6 +2112,12 @@ function getMaximumCompressedSize(uncompressedSize) {
|
|
|
1988
2112
|
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
1989
2113
|
}
|
|
1990
2114
|
|
|
2115
|
+
function isCompressed(compressionMethod, level) {
|
|
2116
|
+
return compressionMethod === UNDEFINED_VALUE
|
|
2117
|
+
? (level === UNDEFINED_VALUE || level > 0)
|
|
2118
|
+
: compressionMethod !== COMPRESSION_METHOD_STORE;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
1991
2121
|
function setUint8(view, offset, value) {
|
|
1992
2122
|
view.setUint8(offset, value);
|
|
1993
2123
|
}
|
package/lib/zip-core-writer.js
CHANGED
|
@@ -33,6 +33,7 @@ export {
|
|
|
33
33
|
ZipWriterStream,
|
|
34
34
|
ERR_DUPLICATED_NAME,
|
|
35
35
|
ERR_INVALID_COMMENT,
|
|
36
|
+
ERR_INVALID_COMMENT_TYPE,
|
|
36
37
|
ERR_INVALID_ENTRY_NAME,
|
|
37
38
|
ERR_INVALID_ENTRY_COMMENT,
|
|
38
39
|
ERR_INVALID_VERSION,
|
|
@@ -40,8 +41,10 @@ export {
|
|
|
40
41
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
41
42
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
42
43
|
ERR_UNSUPPORTED_ENCRYPTION_USDZ,
|
|
44
|
+
ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH,
|
|
43
45
|
ERR_UNSUPPORTED_FORMAT,
|
|
44
46
|
ERR_UNDEFINED_UNCOMPRESSED_SIZE,
|
|
47
|
+
ERR_UNDETERMINED_SIZE,
|
|
45
48
|
ERR_UNDEFINED_READER,
|
|
46
49
|
ERR_ZIP_NOT_EMPTY,
|
|
47
50
|
ERR_INVALID_SIGNATURE_DATA,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A JavaScript library to zip and unzip files in the browser, Deno and Node.js",
|
|
4
4
|
"author": "Gildas Lormeau",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
|
-
"version": "2.8.
|
|
6
|
+
"version": "2.8.53",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"zip",
|
|
@@ -35,25 +35,27 @@
|
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"lint": "npx eslint . && deno lint",
|
|
38
|
-
"test": "npm run test-node && npm run test-deno && npm run test-bun && npm run test-node-dist && npm run test-deno-dist && npm run test-bun-dist && npm run test-web-streams-polyfill && npm run test-types",
|
|
39
|
-
"test-browsers": "npm run test-chrome && npm run test-firefox && npm run test-
|
|
38
|
+
"test": "npm run test-node && npm run test-deno && npm run test-bun && npm run test-node-dist && npm run test-deno-dist && npm run test-bun-dist && npm run test-web-streams-polyfill && npm run test-types && npm run test-api-symmetry && npm run test-api-shape",
|
|
39
|
+
"test-browsers": "npm run test-chrome && npm run test-firefox && npm run test-safari",
|
|
40
40
|
"serve-tests": "http-server -p 8888 -c-1 .",
|
|
41
41
|
"test-all": "npm run lint && npm run test && npm run test-browsers",
|
|
42
42
|
"build": "npx rollup -c",
|
|
43
43
|
"build-dev": "npx rollup -c --environment DEV",
|
|
44
44
|
"build-doc-api": "npx typedoc",
|
|
45
|
-
"build-doc-markdown": "npx typedoc --plugin typedoc-plugin-markdown --out ./docs",
|
|
45
|
+
"build-doc-markdown": "npx typedoc --plugin typedoc-plugin-markdown --disableSources --out ./docs",
|
|
46
46
|
"test-deno": "cd ./tests && deno test --allow-read ./deno-runner.js",
|
|
47
47
|
"test-web-streams-polyfill": "cd ./tests && deno run --allow-read ./web-streams-polyfill-runner.js",
|
|
48
48
|
"test-node": "cd ./tests && node ./node-runner.js",
|
|
49
|
-
"test-bun": "cd ./tests && bun test ./bun-runner.js
|
|
49
|
+
"test-bun": "cd ./tests && bun test ./bun-runner.js",
|
|
50
50
|
"test-deno-dist": "./tests/dist-runner.sh deno",
|
|
51
51
|
"test-node-dist": "./tests/dist-runner.sh node",
|
|
52
52
|
"test-bun-dist": "./tests/dist-runner.sh bun",
|
|
53
53
|
"test-types": "tsc -p ./tests/types/tsconfig.json",
|
|
54
|
+
"test-api-symmetry": "node ./tests/api-symmetry/audit.js",
|
|
55
|
+
"test-api-shape": "node ./tests/api-symmetry/shape.js",
|
|
54
56
|
"test-firefox": "node ./tests/browser-runner.js firefox",
|
|
55
57
|
"test-chrome": "node ./tests/browser-runner.js chrome",
|
|
56
|
-
"test-
|
|
58
|
+
"test-safari": "node ./tests/browser-runner.js safari"
|
|
57
59
|
},
|
|
58
60
|
"main": "./index.cjs",
|
|
59
61
|
"module": "./index.js",
|
|
@@ -260,8 +262,8 @@
|
|
|
260
262
|
"@rollup/plugin-terser": "^1.0.0",
|
|
261
263
|
"eslint": "^10.8.1",
|
|
262
264
|
"http-server": "^14.1.1",
|
|
263
|
-
"playwright": "^1.62.1",
|
|
264
265
|
"rollup": "^4.62.4",
|
|
266
|
+
"selenium-webdriver": "^4.47.0",
|
|
265
267
|
"typedoc": "^0.28.20",
|
|
266
268
|
"typedoc-plugin-markdown": "^4.12.0",
|
|
267
269
|
"web-streams-polyfill": "^4.3.0",
|