@zip.js/zip.js 2.18.1 → 2.19.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 (44) hide show
  1. package/BENCHMARKS.md +122 -118
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +59 -94
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +59 -94
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +59 -94
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +59 -94
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +59 -94
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +61 -96
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +60 -95
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +61 -96
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-native.js +61 -96
  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 +60 -95
  24. package/dist/zip.min.js +1 -1
  25. package/index-native.cjs +61 -96
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +60 -95
  28. package/index.d.cts +33 -23
  29. package/index.d.ts +33 -23
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +1 -2
  32. package/lib/core/codec-worker-web.js +11 -39
  33. package/lib/core/codec-worker.js +1 -2
  34. package/lib/core/configuration.js +1 -1
  35. package/lib/core/options.js +0 -2
  36. package/lib/core/streams/codec-stream.js +1 -1
  37. package/lib/core/version.js +1 -1
  38. package/lib/core/web-worker-base.js +2 -3
  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-reader.js +26 -36
  42. package/lib/core/zip-writer.js +18 -14
  43. package/package.json +1 -1
  44. package/worker-message-property-names.js +1 -1
@@ -175,7 +175,6 @@ import {
175
175
  STRICTNESS_TOLERANT,
176
176
  OPTION_USE_WEB_WORKERS,
177
177
  OPTION_USE_COMPRESSION_STREAM,
178
- OPTION_TRANSFER_STREAMS,
179
178
  OPTION_PREVENT_CLOSE,
180
179
  checkFunctionOption,
181
180
  checkSignalOption,
@@ -499,17 +498,6 @@ class ZipReader {
499
498
  if (filename === UNDEFINED_VALUE) {
500
499
  filename = decodeText(rawFilename, rawFilenameEncoding);
501
500
  }
502
- if (normalizeFilename) {
503
- const normalizedFilename = normalizeFilename(filename);
504
- if (normalizedFilename !== UNDEFINED_VALUE) {
505
- filename = normalizedFilename;
506
- }
507
- }
508
- if (isUnsafeFilename(filename, filenameValidation)) {
509
- const error = new Error(ERR_UNSAFE_FILENAME);
510
- error.filename = filename;
511
- throw error;
512
- }
513
501
  let comment = decode(rawComment, rawCommentEncoding, TEXT_TYPE_COMMENT);
514
502
  if (comment === UNDEFINED_VALUE) {
515
503
  comment = decodeText(rawComment, rawCommentEncoding);
@@ -537,7 +525,20 @@ class ZipReader {
537
525
  filename,
538
526
  comment
539
527
  });
540
- if (readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6)) {
528
+ const malformedExtraField = readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
529
+ filename = fileEntry.filename;
530
+ if (normalizeFilename) {
531
+ const normalizedFilename = normalizeFilename(filename);
532
+ if (normalizedFilename !== UNDEFINED_VALUE) {
533
+ filename = fileEntry.filename = normalizedFilename;
534
+ }
535
+ }
536
+ if (isUnsafeFilename(filename, filenameValidation)) {
537
+ const error = new Error(ERR_UNSAFE_FILENAME);
538
+ error.filename = filename;
539
+ throw error;
540
+ }
541
+ if (malformedExtraField) {
541
542
  addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
542
543
  }
543
544
  fileEntry.offset += prependedDataLength;
@@ -990,7 +991,6 @@ class ZipEntry {
990
991
  encrypted,
991
992
  useWebWorkers: getOptionValue(zipEntry, options, OPTION_USE_WEB_WORKERS),
992
993
  useCompressionStream,
993
- transferStreams: getOptionValue(zipEntry, options, OPTION_TRANSFER_STREAMS),
994
994
  deflate64,
995
995
  format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
996
996
  codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
@@ -1220,19 +1220,17 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
1220
1220
  readExtraFieldNTFS(extraFieldNTFS, directory);
1221
1221
  directory.extraFieldNTFS = extraFieldNTFS;
1222
1222
  }
1223
- const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
1223
+ const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
1224
1224
  let unixIdsRead;
1225
+ if (extraFieldInfoZip) {
1226
+ unixIdsRead = readExtraFieldUnix(extraFieldInfoZip, directory, true);
1227
+ directory.extraFieldInfoZip = extraFieldInfoZip;
1228
+ }
1229
+ const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
1225
1230
  if (extraFieldUnix) {
1226
- unixIdsRead = readExtraFieldUnix(extraFieldUnix, directory, false);
1231
+ readExtraFieldUnix(extraFieldUnix, unixIdsRead ? {} : directory, false);
1227
1232
  directory.extraFieldUnix = extraFieldUnix;
1228
1233
  }
1229
- if (!unixIdsRead) {
1230
- const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
1231
- if (extraFieldInfoZip) {
1232
- readExtraFieldUnix(extraFieldInfoZip, directory, true);
1233
- directory.extraFieldInfoZip = extraFieldInfoZip;
1234
- }
1235
- }
1236
1234
  const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
1237
1235
  if (extraFieldExtendedTimestamp) {
1238
1236
  readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
@@ -1458,19 +1456,11 @@ async function detectOverlappingEntry({
1458
1456
  const zip64 = Boolean(extraFieldZip64);
1459
1457
  const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
1460
1458
  const dataDescriptorView = getDataView(dataDescriptorArray);
1461
- const ignoreCrc32 = fileEntry.encrypted && !fileEntry.zipCrypto;
1462
- let localDataDescriptor;
1463
- for (const [zip64Layout, signature] of [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]) {
1464
- const candidate = readDataDescriptor(dataDescriptorView, zip64Layout, signature);
1465
- if (candidate && (ignoreCrc32 || candidate.crc32 == crc32) &&
1466
- candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize) {
1467
- localDataDescriptor = candidate;
1468
- break;
1469
- }
1470
- }
1471
- if (!localDataDescriptor) {
1472
- localDataDescriptor = readDataDescriptor(dataDescriptorView, zip64, false);
1473
- }
1459
+ const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
1460
+ .map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
1461
+ .filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
1462
+ const localDataDescriptor = candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
1463
+ readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
1474
1464
  if (localDataDescriptor) {
1475
1465
  fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
1476
1466
  dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
@@ -218,7 +218,6 @@ import {
218
218
  OPTION_SIGNAL,
219
219
  OPTION_USE_WEB_WORKERS,
220
220
  OPTION_USE_COMPRESSION_STREAM,
221
- OPTION_TRANSFER_STREAMS,
222
221
  OPTION_PREVENT_CLOSE,
223
222
  OPTION_ENCRYPTION_STRENGTH,
224
223
  OPTION_EXTENDED_TIMESTAMP,
@@ -449,6 +448,7 @@ class ZipWriter {
449
448
  rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
450
449
  rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
451
450
  rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
451
+ rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
452
452
  rawExtraField,
453
453
  rawCentralExtraField: EMPTY_UINT8_ARRAY,
454
454
  headerArray,
@@ -1063,7 +1063,6 @@ function resolveMetadata(zipWriter, name, options) {
1063
1063
  const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
1064
1064
  const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
1065
1065
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
1066
- const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
1067
1066
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
1068
1067
  const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
1069
1068
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
@@ -1129,7 +1128,6 @@ function resolveMetadata(zipWriter, name, options) {
1129
1128
  ntfsTimestamp,
1130
1129
  keepOrder,
1131
1130
  useWebWorkers,
1132
- transferStreams,
1133
1131
  bufferedWrite,
1134
1132
  createTempStream,
1135
1133
  dataDescriptorSignature,
@@ -1188,7 +1186,7 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
1188
1186
  if (reader) {
1189
1187
  reader = new GenericReader(reader);
1190
1188
  await initStream(reader);
1191
- if (!reader.readable && !reader.readUint8Array) {
1189
+ if (!reader.readUint8Array && !reader.readable) {
1192
1190
  throw new Error(ERR_INVALID_READER);
1193
1191
  }
1194
1192
  ({ size: contentSize } = reader);
@@ -1549,6 +1547,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1549
1547
  extraFieldExtendedTimestampTime,
1550
1548
  rawExtraFieldNTFS,
1551
1549
  rawExtraFieldUnix,
1550
+ rawCentralExtraFieldUnix,
1552
1551
  rawExtraFieldAES,
1553
1552
  } = headerInfo;
1554
1553
  const { dataDescriptorArray } = dataDescriptorInfo;
@@ -1573,7 +1572,6 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1573
1572
  rawExtraField,
1574
1573
  rawCentralExtraField,
1575
1574
  useWebWorkers,
1576
- transferStreams,
1577
1575
  onstart,
1578
1576
  onprogress,
1579
1577
  onend,
@@ -1615,6 +1613,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1615
1613
  rawExtraFieldExtendedTimestamp,
1616
1614
  rawExtraFieldNTFS,
1617
1615
  rawExtraFieldUnix,
1616
+ rawCentralExtraFieldUnix,
1618
1617
  rawExtraFieldAES,
1619
1618
  rawExtraField,
1620
1619
  rawCentralExtraField,
@@ -1661,7 +1660,6 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
1661
1660
  encrypted: encrypted && !passThroughEncryption,
1662
1661
  useWebWorkers,
1663
1662
  useCompressionStream,
1664
- transferStreams,
1665
1663
  format,
1666
1664
  codecURI,
1667
1665
  compressionMethod
@@ -1839,6 +1837,7 @@ function getHeaderInfo(options) {
1839
1837
  rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = EMPTY_UINT8_ARRAY;
1840
1838
  }
1841
1839
  let rawExtraFieldUnix;
1840
+ let rawCentralExtraFieldUnix;
1842
1841
  try {
1843
1842
  const { uid, gid, unixExtraFieldType } = options;
1844
1843
  if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
@@ -1853,7 +1852,7 @@ function getHeaderInfo(options) {
1853
1852
  extraFieldUnix.writeBytes(uidBytes);
1854
1853
  extraFieldUnix.writeUint8(gidBytes.length);
1855
1854
  extraFieldUnix.writeBytes(gidBytes);
1856
- rawExtraFieldUnix = extraFieldUnix.array;
1855
+ rawExtraFieldUnix = rawCentralExtraFieldUnix = extraFieldUnix.array;
1857
1856
  } else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
1858
1857
  const extraFieldUnix = createRecordWriter(8);
1859
1858
  extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
@@ -1861,11 +1860,15 @@ function getHeaderInfo(options) {
1861
1860
  extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
1862
1861
  extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
1863
1862
  rawExtraFieldUnix = extraFieldUnix.array;
1863
+ const centralExtraFieldUnix = createRecordWriter(4);
1864
+ centralExtraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
1865
+ centralExtraFieldUnix.writeUint16(0);
1866
+ rawCentralExtraFieldUnix = centralExtraFieldUnix.array;
1864
1867
  } else {
1865
- rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
1868
+ rawExtraFieldUnix = rawCentralExtraFieldUnix = EMPTY_UINT8_ARRAY;
1866
1869
  }
1867
1870
  } catch {
1868
- rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
1871
+ rawExtraFieldUnix = rawCentralExtraFieldUnix = EMPTY_UINT8_ARRAY;
1869
1872
  }
1870
1873
  if (compressionMethod === UNDEFINED_VALUE) {
1871
1874
  compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
@@ -1957,6 +1960,7 @@ function getHeaderInfo(options) {
1957
1960
  rawExtraFieldExtendedTimestamp,
1958
1961
  rawExtraFieldNTFS,
1959
1962
  rawExtraFieldUnix,
1963
+ rawCentralExtraFieldUnix,
1960
1964
  rawExtraFieldAES,
1961
1965
  extraFieldLength
1962
1966
  };
@@ -2132,7 +2136,7 @@ function createDirectoryRecords(files) {
2132
2136
  rawExtraFieldAES,
2133
2137
  rawComment,
2134
2138
  rawExtraFieldNTFS,
2135
- rawExtraFieldUnix,
2139
+ rawCentralExtraFieldUnix,
2136
2140
  rawExtraField,
2137
2141
  rawCentralExtraField,
2138
2142
  extraFieldExtendedTimestampFlag,
@@ -2194,7 +2198,7 @@ function createDirectoryRecords(files) {
2194
2198
  rawExtraFieldZip64,
2195
2199
  rawExtraFieldAES,
2196
2200
  rawExtraFieldNTFS,
2197
- rawExtraFieldUnix,
2201
+ rawCentralExtraFieldUnix,
2198
2202
  rawExtraFieldTimestamp,
2199
2203
  rawExtraField,
2200
2204
  rawCentralExtraField);
@@ -2223,7 +2227,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
2223
2227
  rawExtraFieldAES,
2224
2228
  rawExtraFieldExtendedTimestamp,
2225
2229
  rawExtraFieldNTFS,
2226
- rawExtraFieldUnix,
2230
+ rawCentralExtraFieldUnix,
2227
2231
  rawExtraField,
2228
2232
  rawCentralExtraField,
2229
2233
  rawComment,
@@ -2240,7 +2244,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
2240
2244
  uncompressedSize,
2241
2245
  compressedSize
2242
2246
  } = fileEntry;
2243
- const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawCentralExtraField);
2247
+ const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawCentralExtraFieldUnix, rawExtraField, rawCentralExtraField);
2244
2248
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
2245
2249
  if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
2246
2250
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
@@ -2276,7 +2280,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
2276
2280
  directoryRecord.writeBytes(rawExtraFieldAES);
2277
2281
  directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
2278
2282
  directoryRecord.writeBytes(rawExtraFieldNTFS);
2279
- directoryRecord.writeBytes(rawExtraFieldUnix);
2283
+ directoryRecord.writeBytes(rawCentralExtraFieldUnix);
2280
2284
  directoryRecord.writeBytes(rawExtraField);
2281
2285
  directoryRecord.writeBytes(rawCentralExtraField);
2282
2286
  directoryRecord.writeBytes(rawComment);
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.18.1",
6
+ "version": "2.19.0",
7
7
  "type": "module",
8
8
  "keywords": [
9
9
  "zip",
@@ -1,3 +1,3 @@
1
- const WORKER_MESSAGE_PROPERTY_NAMES = ["baseURI", "cause", "checkAuthenticationCode", "checkCrc32", "checkPasswordOnly", "chunkSize", "code", "codecImportFailed", "codecType", "codecURI", "compressed", "compressionMethod", "computeCrc32", "config", "crc32", "deflate64", "done", "encrypted", "encryptionStrength", "error", "errorValue", "format", "inputSize", "level", "message", "messageId", "name", "options", "outputSize", "password", "passwordVerification", "rawBitFlag", "rawPassword", "readable", "result", "stack", "transferStreams", "type", "useCompressionStream", "useWebWorkers", "value", "wasmURI", "workerStartupTimeout", "writable", "zipCrypto"];
1
+ const WORKER_MESSAGE_PROPERTY_NAMES = ["baseURI", "cause", "checkAuthenticationCode", "checkCrc32", "checkPasswordOnly", "chunkSize", "code", "codecImportFailed", "codecType", "codecURI", "compressed", "compressionMethod", "computeCrc32", "config", "crc32", "deflate64", "done", "encrypted", "encryptionStrength", "error", "errorValue", "format", "inputSize", "level", "message", "messageId", "name", "options", "outputSize", "password", "passwordVerification", "rawBitFlag", "rawPassword", "result", "stack", "type", "useCompressionStream", "useWebWorkers", "value", "wasmURI", "workerStartupTimeout", "zipCrypto"];
2
2
 
3
3
  export { WORKER_MESSAGE_PROPERTY_NAMES };