@zip.js/zip.js 2.16.1 → 2.18.0

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/deno.json +1 -1
  2. package/dist/zip-core-external.js +211 -130
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +180 -117
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +223 -132
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +192 -119
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +223 -132
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +194 -121
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +224 -132
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +181 -118
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +182 -119
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +212 -130
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +194 -121
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +224 -132
  27. package/index.d.cts +87 -24
  28. package/index.d.ts +87 -24
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +2 -0
  31. package/lib/core/codec-worker-web.js +16 -3
  32. package/lib/core/codec-worker.js +2 -1
  33. package/lib/core/streams/codec-stream.js +2 -0
  34. package/lib/core/streams/zip-entry-stream.js +123 -102
  35. package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
  36. package/lib/core/streams/zlib-wasm/zlib-streams.js +31 -12
  37. package/lib/core/version.js +1 -1
  38. package/lib/core/web-worker-base.js +2 -2
  39. package/lib/core/web-worker-inline-native.js +1 -1
  40. package/lib/core/web-worker-inline-wasm.js +1 -1
  41. package/lib/core/zip-fs.js +16 -3
  42. package/lib/core/zip-reader.js +40 -11
  43. package/lib/core/zip-writer.js +1 -0
  44. package/lib/zip-core-reader.js +1 -0
  45. package/package.json +1 -1
@@ -108,6 +108,7 @@ import {
108
108
  ERR_INVALID_PASSWORD,
109
109
  ERR_INVALID_UNCOMPRESSED_SIZE,
110
110
  ERR_INVALID_COMPRESSED_DATA,
111
+ ERR_CODEC_OUT_OF_MEMORY,
111
112
  ERR_ABORT_CHECK_PASSWORD,
112
113
  ERR_WORKER_STARTUP_TIMEOUT
113
114
  } from "./codec-pool.js";
@@ -225,7 +226,7 @@ const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
225
226
  const CHARSET_UTF8 = "utf-8";
226
227
  const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
227
228
  const CHARSET_CP437 = "cp437";
228
- const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
229
+ const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_STRONG_ENCRYPTION | BITFLAG_LANG_ENCODING_FLAG;
229
230
  const VENDOR_VERSION_AE_1 = 1;
230
231
  const ZIP64_PROPERTIES = [
231
232
  [PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
@@ -803,6 +804,7 @@ export {
803
804
  ERR_INVALID_PASSWORD,
804
805
  ERR_INVALID_UNCOMPRESSED_SIZE,
805
806
  ERR_INVALID_COMPRESSED_DATA,
807
+ ERR_CODEC_OUT_OF_MEMORY,
806
808
  ERR_SPLIT_ZIP_FILE,
807
809
  ERR_OVERLAPPING_ENTRY,
808
810
  ERR_ENTRY_DATA_OUT_OF_BOUNDS,
@@ -927,12 +929,12 @@ class ZipEntry {
927
929
  fileEntry.gid = gid;
928
930
  }
929
931
  const checkPasswordOnly = getOptionValue(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
930
- const encrypted = zipEntry.encrypted && localDirectory.encrypted && (!passThroughEncryption || checkPasswordOnly);
932
+ const encrypted = zipEntry.encrypted && (!passThroughEncryption || checkPasswordOnly);
931
933
  const zipCrypto = encrypted && !extraFieldAES;
932
934
  if (!passThroughEncryption) {
933
935
  fileEntry.zipCrypto = zipCrypto;
934
936
  }
935
- if (encrypted && (localDirectory.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
937
+ if (encrypted && (zipEntry.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
936
938
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
937
939
  }
938
940
  const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
@@ -1025,6 +1027,7 @@ class ZipEntry {
1025
1027
  ({ writable } = writer);
1026
1028
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
1027
1029
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
1030
+ throwIfAborted(signal);
1028
1031
  if (writtenSize != outputSize) {
1029
1032
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
1030
1033
  }
@@ -1171,8 +1174,16 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
1171
1174
  });
1172
1175
  const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
1173
1176
  if (extraFieldZip64) {
1174
- readExtraFieldZip64(extraFieldZip64, directory);
1177
+ if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
1178
+ malformedExtraField = true;
1179
+ }
1175
1180
  directory.extraFieldZip64 = extraFieldZip64;
1181
+ } else if (ZIP64_PROPERTIES.some(([propertyName, max]) => directory[propertyName] == max)) {
1182
+ if (localDirectory) {
1183
+ malformedExtraField = true;
1184
+ } else {
1185
+ throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
1186
+ }
1176
1187
  }
1177
1188
  const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
1178
1189
  if (extraFieldUnicodePath) {
@@ -1185,10 +1196,13 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
1185
1196
  directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
1186
1197
  }
1187
1198
  const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
1188
- if (extraFieldAES && extraFieldAES.data.length >= 7) {
1199
+ if (extraFieldAES && (compressionMethod == COMPRESSION_METHOD_AES || directory.encrypted) && extraFieldAES.data.length >= 7) {
1189
1200
  readExtraFieldAES(extraFieldAES, directory, compressionMethod);
1190
1201
  directory.extraFieldAES = extraFieldAES;
1191
1202
  } else {
1203
+ if (extraFieldAES) {
1204
+ malformedExtraField = true;
1205
+ }
1192
1206
  directory.compressionMethod = compressionMethod;
1193
1207
  }
1194
1208
  const extraFieldPkwareUnix = extraField.get(EXTRAFIELD_TYPE_PKWARE_UNIX);
@@ -1231,20 +1245,35 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
1231
1245
  return malformedExtraField;
1232
1246
  }
1233
1247
 
1234
- function readExtraFieldZip64(extraFieldZip64, directory) {
1248
+ function readExtraFieldZip64(extraFieldZip64, directory, localDirectory) {
1235
1249
  directory.zip64 = true;
1236
1250
  const extraFieldView = getDataView(extraFieldZip64.data);
1237
1251
  const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
1238
1252
  const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
1239
1253
  if (extraFieldZip64.data.length < requiredLength) {
1254
+ if (localDirectory) {
1255
+ return false;
1256
+ }
1240
1257
  throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
1241
1258
  }
1242
- for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
1243
- const [propertyName, max] = missingProperties[indexMissingProperty];
1244
- const extraction = ZIP64_EXTRACTION[max];
1245
- directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
1246
- offset += extraction.bytes;
1259
+ const values = [];
1260
+ try {
1261
+ for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
1262
+ const [, max] = missingProperties[indexMissingProperty];
1263
+ const extraction = ZIP64_EXTRACTION[max];
1264
+ values.push(extraction.getValue(extraFieldView, offset));
1265
+ offset += extraction.bytes;
1266
+ }
1267
+ } catch (error) {
1268
+ if (localDirectory) {
1269
+ return false;
1270
+ }
1271
+ throw error;
1247
1272
  }
1273
+ missingProperties.forEach(([propertyName], indexMissingProperty) => {
1274
+ directory[propertyName] = extraFieldZip64[propertyName] = values[indexMissingProperty];
1275
+ });
1276
+ return true;
1248
1277
  }
1249
1278
 
1250
1279
  function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
@@ -1673,6 +1673,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1673
1673
  const result = await runWorker({ readable, writable }, workerOptions);
1674
1674
  compressedSize = result.outputSize;
1675
1675
  writer.size += compressedSize;
1676
+ throwIfAborted(signal);
1676
1677
  if (!passThroughCompression) {
1677
1678
  uncompressedSize = result.inputSize;
1678
1679
  if (!encrypted || zipCrypto) {
@@ -46,6 +46,7 @@ export {
46
46
  ERR_INVALID_UNCOMPRESSED_SIZE,
47
47
  ERR_INVALID_PASSWORD,
48
48
  ERR_INVALID_COMPRESSED_DATA,
49
+ ERR_CODEC_OUT_OF_MEMORY,
49
50
  ERR_SPLIT_ZIP_FILE,
50
51
  ERR_OVERLAPPING_ENTRY,
51
52
  ERR_ENTRY_DATA_OUT_OF_BOUNDS,
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.16.1",
6
+ "version": "2.18.0",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",