@zip.js/zip.js 2.7.33 → 2.7.34

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.
@@ -56,26 +56,28 @@ let indexWorker = 0;
56
56
  async function runWorker(stream, workerOptions) {
57
57
  const { options, config } = workerOptions;
58
58
  const { transferStreams, useWebWorkers, useCompressionStream, codecType, compressed, signed, encrypted } = options;
59
- const { workerScripts, maxWorkers, terminateWorkerTimeout } = config;
59
+ const { workerScripts, maxWorkers } = config;
60
60
  workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
61
61
  const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
62
62
  workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
63
63
  workerOptions.scripts = workerOptions.useWebWorkers && workerScripts ? workerScripts[codecType] : [];
64
64
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
65
- let worker;
66
- const workerData = pool.find(workerData => !workerData.busy);
67
- if (workerData) {
68
- clearTerminateTimeout(workerData);
69
- worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
70
- } else if (pool.length < maxWorkers) {
71
- const workerData = { indexWorker };
72
- indexWorker++;
73
- pool.push(workerData);
74
- worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
75
- } else {
76
- worker = await new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
65
+ return (await getWorker()).run();
66
+
67
+ async function getWorker() {
68
+ const workerData = pool.find(workerData => !workerData.busy);
69
+ if (workerData) {
70
+ clearTerminateTimeout(workerData);
71
+ return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
72
+ } else if (pool.length < maxWorkers) {
73
+ const workerData = { indexWorker };
74
+ indexWorker++;
75
+ pool.push(workerData);
76
+ return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
77
+ } else {
78
+ return new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
79
+ }
77
80
  }
78
- return worker.run();
79
81
 
80
82
  function onTaskFinished(workerData) {
81
83
  if (pendingRequests.length) {
@@ -83,26 +85,32 @@ async function runWorker(stream, workerOptions) {
83
85
  resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
84
86
  } else if (workerData.worker) {
85
87
  clearTerminateTimeout(workerData);
86
- if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
87
- if (workerData.terminated) {
88
- workerData.terminated = false;
89
- } else {
90
- workerData.terminateTimeout = setTimeout(async () => {
91
- pool = pool.filter(data => data != workerData);
92
- try {
93
- await workerData.terminate();
94
- } catch (_error) {
95
- // ignored
96
- }
97
- }, terminateWorkerTimeout);
98
- }
99
- }
88
+ terminateWorker(workerData, workerOptions);
100
89
  } else {
101
90
  pool = pool.filter(data => data != workerData);
102
91
  }
103
92
  }
104
93
  }
105
94
 
95
+ function terminateWorker(workerData, workerOptions) {
96
+ const { config } = workerOptions;
97
+ const { terminateWorkerTimeout } = config;
98
+ if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
99
+ if (workerData.terminated) {
100
+ workerData.terminated = false;
101
+ } else {
102
+ workerData.terminateTimeout = setTimeout(async () => {
103
+ pool = pool.filter(data => data != workerData);
104
+ try {
105
+ await workerData.terminate();
106
+ } catch (_error) {
107
+ // ignored
108
+ }
109
+ }, terminateWorkerTimeout);
110
+ }
111
+ }
112
+ }
113
+
106
114
  function clearTerminateTimeout(workerData) {
107
115
  const { terminateTimeout } = workerData;
108
116
  if (terminateTimeout) {
@@ -100,9 +100,9 @@ class ProgressWatcherStream extends TransformStream {
100
100
  constructor(readableSource, { onstart, onprogress, size, onend }) {
101
101
  let chunkOffset = 0;
102
102
  super({
103
- start() {
103
+ async start() {
104
104
  if (onstart) {
105
- callHandler(onstart, size);
105
+ await callHandler(onstart, size);
106
106
  }
107
107
  },
108
108
  async transform(chunk, controller) {
@@ -112,10 +112,10 @@ class ProgressWatcherStream extends TransformStream {
112
112
  }
113
113
  controller.enqueue(chunk);
114
114
  },
115
- flush() {
115
+ async flush() {
116
116
  readableSource.size = chunkOffset;
117
117
  if (onend) {
118
- callHandler(onend, chunkOffset);
118
+ await callHandler(onend, chunkOffset);
119
119
  }
120
120
  }
121
121
  });
package/lib/core/io.js CHANGED
@@ -262,7 +262,7 @@ class FetchReader extends Reader {
262
262
 
263
263
  constructor(url, options) {
264
264
  super();
265
- createHtpReader(this, url, options);
265
+ createHttpReader(this, url, options);
266
266
  }
267
267
 
268
268
  async init() {
@@ -279,7 +279,7 @@ class XHRReader extends Reader {
279
279
 
280
280
  constructor(url, options) {
281
281
  super();
282
- createHtpReader(this, url, options);
282
+ createHttpReader(this, url, options);
283
283
  }
284
284
 
285
285
  async init() {
@@ -292,7 +292,7 @@ class XHRReader extends Reader {
292
292
  }
293
293
  }
294
294
 
295
- function createHtpReader(httpReader, url, options) {
295
+ function createHttpReader(httpReader, url, options) {
296
296
  const {
297
297
  preventHeadRequest,
298
298
  useRangeHeader,
@@ -689,8 +689,7 @@ function initWriter(writer) {
689
689
  if (writable.size === UNDEFINED_VALUE) {
690
690
  writable.size = 0;
691
691
  }
692
- const splitZipFile = writer instanceof SplitDataWriter;
693
- if (!splitZipFile) {
692
+ if (!(writer instanceof SplitDataWriter)) {
694
693
  Object.assign(writer, {
695
694
  diskNumber: 0,
696
695
  diskOffset: 0,
@@ -29,6 +29,7 @@
29
29
  /* global crypto, TransformStream */
30
30
  // deno-lint-ignore-file no-this-alias
31
31
 
32
+ import { UNDEFINED_VALUE, UNDEFINED_TYPE, FUNCTION_TYPE } from "../constants.js";
32
33
  import { encodeText } from "./../util/encode-text.js";
33
34
  import {
34
35
  cipher,
@@ -55,8 +56,6 @@ const SALT_LENGTH = [8, 12, 16];
55
56
  const KEY_LENGTH = [16, 24, 32];
56
57
  const SIGNATURE_LENGTH = 10;
57
58
  const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
58
- const UNDEFINED_TYPE = "undefined";
59
- const FUNCTION_TYPE = "function";
60
59
  // deno-lint-ignore valid-typeof
61
60
  const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
62
61
  const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
@@ -71,12 +70,12 @@ let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && type
71
70
 
72
71
  class AESDecryptionStream extends TransformStream {
73
72
 
74
- constructor({ password, signed, encryptionStrength, checkPasswordOnly }) {
73
+ constructor({ password, rawPassword, signed, encryptionStrength, checkPasswordOnly }) {
75
74
  super({
76
75
  start() {
77
76
  Object.assign(this, {
78
77
  ready: new Promise(resolve => this.resolveReady = resolve),
79
- password,
78
+ password: encodePassword(password, rawPassword),
80
79
  signed,
81
80
  strength: encryptionStrength - 1,
82
81
  pending: new Uint8Array()
@@ -140,14 +139,14 @@ class AESDecryptionStream extends TransformStream {
140
139
 
141
140
  class AESEncryptionStream extends TransformStream {
142
141
 
143
- constructor({ password, encryptionStrength }) {
142
+ constructor({ password, rawPassword, encryptionStrength }) {
144
143
  // deno-lint-ignore prefer-const
145
144
  let stream;
146
145
  super({
147
146
  start() {
148
147
  Object.assign(this, {
149
148
  ready: new Promise(resolve => this.resolveReady = resolve),
150
- password,
149
+ password: encodePassword(password, rawPassword),
151
150
  strength: encryptionStrength - 1,
152
151
  pending: new Uint8Array()
153
152
  });
@@ -244,8 +243,7 @@ async function createEncryptionKeys(encrypt, strength, password) {
244
243
 
245
244
  async function createKeys(aesCrypto, strength, password, salt) {
246
245
  aesCrypto.password = null;
247
- const encodedPassword = encodeText(password);
248
- const baseKey = await importKey(RAW_FORMAT, encodedPassword, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
246
+ const baseKey = await importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
249
247
  const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2));
250
248
  const compositeKey = new Uint8Array(derivedBits);
251
249
  const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength]));
@@ -289,6 +287,14 @@ async function deriveBits(algorithm, baseKey, length) {
289
287
  }
290
288
  }
291
289
 
290
+ function encodePassword(password, rawPassword) {
291
+ if (rawPassword === UNDEFINED_VALUE) {
292
+ return encodeText(password);
293
+ } else {
294
+ return rawPassword;
295
+ }
296
+ }
297
+
292
298
  function concat(leftArray, rightArray) {
293
299
  let array = leftArray;
294
300
  if (leftArray.length + rightArray.length) {
@@ -28,11 +28,12 @@
28
28
 
29
29
  /* global crypto */
30
30
 
31
+ import { FUNCTION_TYPE, UNDEFINED_TYPE } from "../constants.js";
31
32
  import {
32
33
  random
33
34
  } from "./codecs/sjcl.js";
34
35
 
35
- const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != "undefined" && typeof crypto.getRandomValues == "function";
36
+ const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != UNDEFINED_TYPE && typeof crypto.getRandomValues == FUNCTION_TYPE;
36
37
 
37
38
  const ERR_INVALID_PASSWORD = "Invalid password";
38
39
  const ERR_INVALID_SIGNATURE = "Invalid signature";
@@ -28,12 +28,14 @@
28
28
 
29
29
  /* global TextEncoder */
30
30
 
31
+ import { UNDEFINED_TYPE } from "../constants.js";
32
+
31
33
  export {
32
34
  encodeText
33
35
  };
34
36
 
35
37
  function encodeText(value) {
36
- if (typeof TextEncoder == "undefined") {
38
+ if (typeof TextEncoder == UNDEFINED_TYPE) {
37
39
  value = unescape(encodeURIComponent(value));
38
40
  const result = new Uint8Array(value.length);
39
41
  for (let i = 0; i < result.length; i++) {
@@ -29,6 +29,8 @@
29
29
 
30
30
  // deno-lint-ignore-file no-this-alias
31
31
 
32
+ import { FUNCTION_TYPE, UNDEFINED_VALUE } from "../constants.js";
33
+
32
34
  export {
33
35
  initShimAsyncCodec
34
36
  };
@@ -42,7 +44,7 @@ function initShimAsyncCodec(library, options = {}, registerDataHandler) {
42
44
 
43
45
  function objectHasOwn(object, propertyName) {
44
46
  // eslint-disable-next-line no-prototype-builtins
45
- return typeof Object.hasOwn === "function" ? Object.hasOwn(object, propertyName) : object.hasOwnProperty(propertyName);
47
+ return typeof Object.hasOwn === FUNCTION_TYPE ? Object.hasOwn(object, propertyName) : object.hasOwnProperty(propertyName);
46
48
  }
47
49
 
48
50
  function createCodecClass(constructor, constructorOptions, registerDataHandler) {
@@ -61,7 +63,7 @@ function createCodecClass(constructor, constructorOptions, registerDataHandler)
61
63
  codecAdapter.pendingData = new Uint8Array(data);
62
64
  }
63
65
  };
64
- if (objectHasOwn(options, "level") && options.level === undefined) {
66
+ if (objectHasOwn(options, "level") && options.level === UNDEFINED_VALUE) {
65
67
  delete options.level;
66
68
  }
67
69
  codecAdapter.codec = new constructor(Object.assign({}, constructorOptions, options));
@@ -52,6 +52,7 @@ import {
52
52
  import {
53
53
  Entry
54
54
  } from "./zip-entry.js";
55
+ import { UNDEFINED_VALUE } from "./constants.js";
55
56
 
56
57
  class ZipEntry {
57
58
 
@@ -433,7 +434,7 @@ class ZipDirectoryEntry extends ZipEntry {
433
434
 
434
435
  async exportZip(writer, options) {
435
436
  const zipEntry = this;
436
- if (options.bufferedWrite === undefined) {
437
+ if (options.bufferedWrite === UNDEFINED_VALUE) {
437
438
  options.bufferedWrite = true;
438
439
  }
439
440
  await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
@@ -372,7 +372,9 @@ class ZipEntry {
372
372
  const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
373
373
  const dataView = getDataView(dataArray);
374
374
  let password = getOptionValue(zipEntry, options, "password");
375
+ let rawPassword = getOptionValue(zipEntry, options, "rawPassword");
375
376
  password = password && password.length && password;
377
+ rawPassword = rawPassword && rawPassword.length && rawPassword;
376
378
  if (extraFieldAES) {
377
379
  if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
378
380
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
@@ -398,7 +400,7 @@ class ZipEntry {
398
400
  if (encrypted) {
399
401
  if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
400
402
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
401
- } else if (!password) {
403
+ } else if (!password && !rawPassword) {
402
404
  throw new Error(ERR_ENCRYPTED);
403
405
  }
404
406
  }
@@ -423,6 +425,7 @@ class ZipEntry {
423
425
  options: {
424
426
  codecType: CODEC_INFLATE,
425
427
  password,
428
+ rawPassword,
426
429
  zipCrypto,
427
430
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
428
431
  signed: getOptionValue(zipEntry, options, "checkSignature"),
@@ -452,7 +455,7 @@ class ZipEntry {
452
455
  await writable.getWriter().close();
453
456
  }
454
457
  }
455
- return checkPasswordOnly ? undefined : writer.getData ? writer.getData() : writable;
458
+ return checkPasswordOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable;
456
459
  }
457
460
  }
458
461
 
@@ -219,6 +219,7 @@ async function addFile(zipWriter, name, reader, options) {
219
219
  const internalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, 0);
220
220
  const externalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE, 0);
221
221
  const password = getOptionValue(zipWriter, options, "password");
222
+ const rawPassword = getOptionValue(zipWriter, options, "rawPassword");
222
223
  const encryptionStrength = getOptionValue(zipWriter, options, "encryptionStrength", 3);
223
224
  const zipCrypto = getOptionValue(zipWriter, options, "zipCrypto");
224
225
  const extendedTimestamp = getOptionValue(zipWriter, options, "extendedTimestamp", true);
@@ -301,6 +302,7 @@ async function addFile(zipWriter, name, reader, options) {
301
302
  zip64Offset,
302
303
  zip64DiskNumberStart,
303
304
  password,
305
+ rawPassword,
304
306
  level,
305
307
  useWebWorkers,
306
308
  encryptionStrength,
@@ -467,7 +469,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
467
469
  }
468
470
 
469
471
  async function skipDiskIfNeeded(writable) {
470
- if (headerInfo.localHeaderArray.length > writer.availableSize) {
472
+ if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
471
473
  writer.availableSize = 0;
472
474
  await writeData(writable, new Uint8Array());
473
475
  }
@@ -500,6 +502,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
500
502
  lastAccessDate,
501
503
  creationDate,
502
504
  password,
505
+ rawPassword,
503
506
  level,
504
507
  zip64,
505
508
  zip64UncompressedSize,
@@ -556,6 +559,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
556
559
  options: {
557
560
  codecType: CODEC_DEFLATE,
558
561
  level,
562
+ rawPassword,
559
563
  password,
560
564
  encryptionStrength,
561
565
  zipCrypto: encrypted && zipCrypto,
@@ -637,6 +641,7 @@ function getHeaderInfo(options) {
637
641
  lastModDate,
638
642
  lastAccessDate,
639
643
  creationDate,
644
+ rawPassword,
640
645
  password,
641
646
  level,
642
647
  zip64,
@@ -648,7 +653,7 @@ function getHeaderInfo(options) {
648
653
  extendedTimestamp
649
654
  } = options;
650
655
  const compressed = level !== 0 && !directory;
651
- const encrypted = Boolean(password && getLength(password));
656
+ const encrypted = Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword)));
652
657
  let version = options.version;
653
658
  let rawExtraFieldAES;
654
659
  if (encrypted && !zipCrypto) {
@@ -771,7 +776,7 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
771
776
  const { headerInfo } = entryInfo;
772
777
  let { localHeaderArray, extraFieldLength } = headerInfo;
773
778
  let localHeaderArrayView = getDataView(localHeaderArray);
774
- let extraBytesLength = 64 - ((zipWriterOffset + localHeaderArray.length) % 64);
779
+ let extraBytesLength = 64 - ((zipWriterOffset + getLength(localHeaderArray)) % 64);
775
780
  if (extraBytesLength < 4) {
776
781
  extraBytesLength += 64;
777
782
  }
@@ -780,9 +785,9 @@ function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
780
785
  setUint16(extraFieldUSDZView, 0, EXTRAFIELD_TYPE_USDZ);
781
786
  setUint16(extraFieldUSDZView, 2, extraBytesLength - 2);
782
787
  const previousLocalHeaderArray = localHeaderArray;
783
- headerInfo.localHeaderArray = localHeaderArray = new Uint8Array(previousLocalHeaderArray.length + extraBytesLength);
788
+ headerInfo.localHeaderArray = localHeaderArray = new Uint8Array(getLength(previousLocalHeaderArray) + extraBytesLength);
784
789
  arraySet(localHeaderArray, previousLocalHeaderArray);
785
- arraySet(localHeaderArray, rawExtraFieldUSDZ, previousLocalHeaderArray.length);
790
+ arraySet(localHeaderArray, rawExtraFieldUSDZ, getLength(previousLocalHeaderArray));
786
791
  localHeaderArrayView = getDataView(localHeaderArray);
787
792
  setUint16(localHeaderArrayView, 28, extraFieldLength + extraBytesLength);
788
793
  entryInfo.metadataSize += extraBytesLength;
@@ -844,7 +849,7 @@ function setEntryInfo(entryInfo, options) {
844
849
  if (zip64) {
845
850
  const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
846
851
  setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
847
- setUint16(rawExtraFieldZip64View, 2, rawExtraFieldZip64.length - 4);
852
+ setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
848
853
  let rawExtraFieldZip64Offset = 4;
849
854
  if (zip64UncompressedSize) {
850
855
  setUint32(headerView, 18, MAX_32_BITS);
@@ -31,9 +31,10 @@
31
31
 
32
32
  import "./core/z-worker-core.js";
33
33
  import { initShimAsyncCodec } from "./core/util/stream-codec-shim.js";
34
+ import { UNDEFINED_VALUE } from "./core/constants.js";
34
35
 
35
36
  self.initCodec = () => {
36
- const { Deflate, Inflate } = initShimAsyncCodec(fflate, undefined, (codec, onData) => codec.ondata = onData);
37
+ const { Deflate, Inflate } = initShimAsyncCodec(fflate, UNDEFINED_VALUE, (codec, onData) => codec.ondata = onData);
37
38
  self.Deflate = Deflate;
38
39
  self.Inflate = Inflate;
39
40
  };