@zip.js/zip.js 2.8.43 → 2.8.44

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.
Files changed (45) hide show
  1. package/README.md +0 -37
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +67 -47
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +68 -46
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +67 -47
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +66 -46
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +67 -47
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +70 -48
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +69 -47
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +70 -48
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +70 -48
  20. package/dist/zip-native.min.js +1 -1
  21. package/dist/zip-web-worker-native.js +1 -1
  22. package/dist/zip-web-worker.js +1 -1
  23. package/dist/zip.js +69 -47
  24. package/dist/zip.min.js +1 -1
  25. package/index-native.cjs +70 -48
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +69 -47
  28. package/index.d.cts +80 -7
  29. package/index.d.ts +80 -7
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +6 -2
  32. package/lib/core/options.js +4 -0
  33. package/lib/core/streams/aes-crypto-stream.js +4 -4
  34. package/lib/core/streams/codec-stream.js +4 -0
  35. package/lib/core/streams/common-crypto.js +2 -0
  36. package/lib/core/streams/zip-entry-stream.js +12 -8
  37. package/lib/core/web-worker-inline-native.js +1 -1
  38. package/lib/core/web-worker-inline-wasm.js +1 -1
  39. package/lib/core/web-worker-wasm.js +4 -8
  40. package/lib/core/zip-entry.js +3 -0
  41. package/lib/core/zip-reader.js +35 -26
  42. package/lib/core/zip-writer.js +16 -7
  43. package/lib/zip-core-reader.js +2 -0
  44. package/package.json +1 -1
  45. package/worker-message-property-names.js +1 -1
@@ -93,6 +93,8 @@ import {
93
93
  runWorker,
94
94
  CODEC_INFLATE,
95
95
  ERR_INVALID_SIGNATURE,
96
+ ERR_INVALID_CRC32,
97
+ ERR_INVALID_AUTHENTICATION_CODE,
96
98
  ERR_INVALID_PASSWORD,
97
99
  ERR_INVALID_UNCOMPRESSED_SIZE,
98
100
  ERR_INVALID_COMPRESSED_DATA,
@@ -141,6 +143,8 @@ import {
141
143
  OPTION_CHECK_OVERLAPPING_ENTRY,
142
144
  OPTION_CHECK_AMBIGUITY,
143
145
  OPTION_CHECK_SIGNATURE,
146
+ OPTION_CHECK_CRC32,
147
+ OPTION_CHECK_AUTHENTICATION_CODE,
144
148
  OPTION_STRICTNESS,
145
149
  OPTION_MAX_APPENDED_DATA_SIZE,
146
150
  STRICTNESS_STRICT,
@@ -169,6 +173,7 @@ const CHARSET_UTF8 = "utf-8";
169
173
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
170
174
  const CHARSET_CP437 = "cp437";
171
175
  const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
176
+ const VENDOR_VERSION_AE_1 = 1;
172
177
  const ZIP64_PROPERTIES = [
173
178
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
174
179
  [PROPERTY_NAME_COMPRESSED_SIZE, MAX_32_BITS],
@@ -551,6 +556,8 @@ export {
551
556
  ERR_UNSUPPORTED_ENCRYPTION,
552
557
  ERR_UNSUPPORTED_COMPRESSION,
553
558
  ERR_INVALID_SIGNATURE,
559
+ ERR_INVALID_CRC32,
560
+ ERR_INVALID_AUTHENTICATION_CODE,
554
561
  ERR_INVALID_PASSWORD,
555
562
  ERR_INVALID_UNCOMPRESSED_SIZE,
556
563
  ERR_INVALID_COMPRESSED_DATA,
@@ -670,6 +677,11 @@ class ZipEntry {
670
677
  if (deflate64) {
671
678
  useCompressionStream = false;
672
679
  }
680
+ const checkCrc32Option = getOptionValue(zipEntry, options, OPTION_CHECK_CRC32);
681
+ const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
682
+ getOptionValue(zipEntry, options, OPTION_CHECK_SIGNATURE) :
683
+ checkCrc32Option) && !passThrough &&
684
+ (!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1));
673
685
  const workerOptions = {
674
686
  options: {
675
687
  codecType: CODEC_INFLATE,
@@ -677,7 +689,8 @@ class ZipEntry {
677
689
  rawPassword,
678
690
  zipCrypto,
679
691
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
680
- signed: getOptionValue(zipEntry, options, OPTION_CHECK_SIGNATURE) && !passThrough,
692
+ checkCrc32,
693
+ checkAuthenticationCode: getOptionValue(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
681
694
  passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((signature >>> 24) & MAX_8_BITS)),
682
695
  outputSize: passThrough ? compressedSize : uncompressedSize,
683
696
  signature,
@@ -793,6 +806,7 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
793
806
  const compressionMethod = getUint16(dataView, offset + 4);
794
807
  Object.assign(directory, {
795
808
  signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
809
+ crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
796
810
  compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
797
811
  uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
798
812
  });
@@ -894,6 +908,9 @@ function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
894
908
  compressionMethod: getUint16(extraFieldView, 5)
895
909
  });
896
910
  directory.compressionMethod = extraFieldAES.compressionMethod;
911
+ if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1) {
912
+ directory.crc32 = UNDEFINED_VALUE;
913
+ }
897
914
  }
898
915
 
899
916
  function readExtraFieldNTFS(extraFieldNTFS, directory) {
@@ -912,26 +929,22 @@ function readExtraFieldNTFS(extraFieldNTFS, directory) {
912
929
  } catch {
913
930
  // ignored
914
931
  }
915
- try {
916
- if (tag1Data && tag1Data.length == 24) {
917
- const tag1View = getDataView(tag1Data);
918
- const rawLastModDate = tag1View.getBigUint64(0, true);
919
- const rawLastAccessDate = tag1View.getBigUint64(8, true);
920
- const rawCreationDate = tag1View.getBigUint64(16, true);
921
- Object.assign(extraFieldNTFS, {
922
- rawLastModDate,
923
- rawLastAccessDate,
924
- rawCreationDate
925
- });
926
- const lastModDate = getDateNTFS(rawLastModDate);
927
- const lastAccessDate = getDateNTFS(rawLastAccessDate);
928
- const creationDate = getDateNTFS(rawCreationDate);
929
- const extraFieldData = { lastModDate, lastAccessDate, creationDate };
930
- Object.assign(extraFieldNTFS, extraFieldData);
931
- Object.assign(directory, extraFieldData);
932
- }
933
- } catch {
934
- // ignored
932
+ if (tag1Data && tag1Data.length == 24) {
933
+ const tag1View = getDataView(tag1Data);
934
+ const rawLastModDate = tag1View.getBigUint64(0, true);
935
+ const rawLastAccessDate = tag1View.getBigUint64(8, true);
936
+ const rawCreationDate = tag1View.getBigUint64(16, true);
937
+ Object.assign(extraFieldNTFS, {
938
+ rawLastModDate,
939
+ rawLastAccessDate,
940
+ rawCreationDate
941
+ });
942
+ const lastModDate = getDateNTFS(rawLastModDate);
943
+ const lastAccessDate = getDateNTFS(rawLastAccessDate);
944
+ const creationDate = getDateNTFS(rawCreationDate);
945
+ const extraFieldData = { lastModDate, lastAccessDate, creationDate };
946
+ Object.assign(extraFieldNTFS, extraFieldData);
947
+ Object.assign(directory, extraFieldData);
935
948
  }
936
949
  }
937
950
 
@@ -1234,11 +1247,7 @@ function getOptionValue(zipReader, options, name) {
1234
1247
 
1235
1248
  function getDate(timeRaw) {
1236
1249
  const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
1237
- try {
1238
- return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
1239
- } catch {
1240
- // ignored
1241
- }
1250
+ return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
1242
1251
  }
1243
1252
 
1244
1253
  function getDateNTFS(timeRaw) {
@@ -223,6 +223,8 @@ const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
223
223
  const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
224
224
  const MIN_UNIX_TIME = -2147483648;
225
225
  const MAX_UNIX_TIME = 2147483647;
226
+ const MIN_NTFS_TIME = BigInt(0);
227
+ const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
226
228
  const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
227
229
  const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
228
230
  const ERR_UNDEFINED_READER = "Undefined reader";
@@ -1134,9 +1136,12 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
1134
1136
  msdosAttributes
1135
1137
  };
1136
1138
  let {
1137
- signature,
1139
+ crc32: signature,
1138
1140
  uncompressedSize
1139
1141
  } = options;
1142
+ if (signature === UNDEFINED_VALUE) {
1143
+ ({ signature } = options);
1144
+ }
1140
1145
  let compressedSize = 0;
1141
1146
  if (!passThrough) {
1142
1147
  uncompressedSize = 0;
@@ -1154,7 +1159,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
1154
1159
  encryptionStrength,
1155
1160
  zipCrypto: encrypted && zipCrypto,
1156
1161
  passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
1157
- signed: !passThrough,
1162
+ computeCrc32: !passThrough,
1158
1163
  compressed: compressed && !passThrough,
1159
1164
  encrypted: encrypted && !passThrough,
1160
1165
  useWebWorkers,
@@ -1173,7 +1178,9 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
1173
1178
  writer.size += compressedSize;
1174
1179
  if (!passThrough) {
1175
1180
  uncompressedSize = result.inputSize;
1176
- signature = result.signature;
1181
+ if (!encrypted || zipCrypto) {
1182
+ signature = result.signature;
1183
+ }
1177
1184
  }
1178
1185
  if ((!zip64CompressedSize && compressedSize >= MAX_32_BITS) ||
1179
1186
  (!zip64UncompressedSize && uncompressedSize >= MAX_32_BITS)) {
@@ -1212,6 +1219,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
1212
1219
  headerArray,
1213
1220
  headerView,
1214
1221
  signature,
1222
+ crc32: encrypted && !zipCrypto ? UNDEFINED_VALUE : signature,
1215
1223
  extraFieldExtendedTimestampFlag,
1216
1224
  zip64UncompressedSize,
1217
1225
  zip64CompressedSize
@@ -1312,8 +1320,8 @@ function getHeaderInfo(options) {
1312
1320
  extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
1313
1321
  extraFieldNTFS.uint16(24);
1314
1322
  extraFieldNTFS.uint64(lastModTimeNTFS);
1315
- extraFieldNTFS.uint64(getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
1316
- extraFieldNTFS.uint64(getTimeNTFS(creationDate) || lastModTimeNTFS);
1323
+ extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
1324
+ extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
1317
1325
  rawExtraFieldNTFS = extraFieldNTFS.array;
1318
1326
  } catch {
1319
1327
  rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
@@ -1373,7 +1381,7 @@ function getHeaderInfo(options) {
1373
1381
  if (extraFieldLength > MAX_16_BITS) {
1374
1382
  throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
1375
1383
  }
1376
- const dosLastModDate = new Date(Math.ceil(lastModDate.getTime() / 2000) * 2000);
1384
+ const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
1377
1385
  const {
1378
1386
  headerArray,
1379
1387
  headerView,
@@ -1882,7 +1890,8 @@ async function flushBufferedData(readable, writer, signal, onChunkWritten) {
1882
1890
 
1883
1891
  function getTimeNTFS(date) {
1884
1892
  if (date) {
1885
- return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
1893
+ const timeNTFS = ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
1894
+ return timeNTFS < MIN_NTFS_TIME ? MIN_NTFS_TIME : timeNTFS > MAX_NTFS_TIME ? MAX_NTFS_TIME : timeNTFS;
1886
1895
  }
1887
1896
  }
1888
1897
 
@@ -39,6 +39,8 @@ export {
39
39
  ERR_UNSUPPORTED_ENCRYPTION,
40
40
  ERR_UNSUPPORTED_COMPRESSION,
41
41
  ERR_INVALID_SIGNATURE,
42
+ ERR_INVALID_CRC32,
43
+ ERR_INVALID_AUTHENTICATION_CODE,
42
44
  ERR_INVALID_UNCOMPRESSED_SIZE,
43
45
  ERR_INVALID_PASSWORD,
44
46
  ERR_INVALID_COMPRESSED_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.43",
6
+ "version": "2.8.44",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",
@@ -1,3 +1,3 @@
1
- const WORKER_MESSAGE_PROPERTY_NAMES = ["baseURI", "cause", "checkPasswordOnly", "chunkSize", "code", "codecType", "codecURI", "compressed", "compressionMethod", "config", "deflate64", "done", "encrypted", "encryptionStrength", "error", "format", "inputSize", "level", "message", "messageId", "name", "options", "outputSize", "password", "passwordVerification", "rawBitFlag", "rawPassword", "readable", "result", "signature", "signed", "stack", "transferStreams", "type", "useCompressionStream", "useWebWorkers", "value", "wasmURI", "workerStartupTimeout", "writable", "zipCrypto"];
1
+ const WORKER_MESSAGE_PROPERTY_NAMES = ["baseURI", "cause", "checkAuthenticationCode", "checkCrc32", "checkPasswordOnly", "chunkSize", "code", "codecType", "codecURI", "compressed", "compressionMethod", "computeCrc32", "config", "deflate64", "done", "encrypted", "encryptionStrength", "error", "format", "inputSize", "level", "message", "messageId", "name", "options", "outputSize", "password", "passwordVerification", "rawBitFlag", "rawPassword", "readable", "result", "signature", "stack", "transferStreams", "type", "useCompressionStream", "useWebWorkers", "value", "wasmURI", "workerStartupTimeout", "writable", "zipCrypto"];
2
2
 
3
3
  export { WORKER_MESSAGE_PROPERTY_NAMES };