@zip.js/zip.js 2.14.0 → 2.15.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 +350 -454
  2. package/deno.json +1 -1
  3. package/dist/zip-core-external.js +342 -120
  4. package/dist/zip-core-external.min.js +1 -1
  5. package/dist/zip-core.js +340 -113
  6. package/dist/zip-core.min.js +1 -1
  7. package/dist/zip-fs-core-external.js +342 -120
  8. package/dist/zip-fs-core-external.min.js +1 -1
  9. package/dist/zip-fs-core.js +340 -113
  10. package/dist/zip-fs-core.min.js +1 -1
  11. package/dist/zip-fs-external.js +342 -120
  12. package/dist/zip-fs-external.min.js +1 -1
  13. package/dist/zip-fs-native.js +342 -115
  14. package/dist/zip-fs-native.min.js +1 -1
  15. package/dist/zip-fs.js +346 -124
  16. package/dist/zip-fs.min.js +1 -1
  17. package/dist/zip-legacy.js +342 -115
  18. package/dist/zip-legacy.min.js +1 -1
  19. package/dist/zip-module.wasm +0 -0
  20. package/dist/zip-native.js +342 -115
  21. package/dist/zip-native.min.js +1 -1
  22. package/dist/zip-web-worker-native.js +1 -1
  23. package/dist/zip-web-worker.js +1 -1
  24. package/dist/zip.js +346 -124
  25. package/dist/zip.min.js +1 -1
  26. package/index-native.cjs +342 -115
  27. package/index-native.min.js +1 -1
  28. package/index.cjs +346 -124
  29. package/index.d.cts +20 -13
  30. package/index.d.ts +20 -13
  31. package/index.min.js +1 -1
  32. package/lib/core/codec-pool.js +35 -19
  33. package/lib/core/codec-worker.js +9 -6
  34. package/lib/core/streams/codecs/aes-hmac-sha1.js +194 -56
  35. package/lib/core/streams/zip-entry-stream.js +18 -10
  36. package/lib/core/streams/zlib-wasm/zlib-streams.js +2 -7
  37. package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
  38. package/lib/core/util/decode-text.js +15 -1
  39. package/lib/core/version.js +1 -1
  40. package/lib/core/web-worker-inline-native.js +1 -1
  41. package/lib/core/web-worker-inline-wasm.js +1 -1
  42. package/lib/core/zip-reader.js +65 -16
  43. package/lib/core/zlib-streams-inline.js +1 -1
  44. package/package.json +1 -1
@@ -106,7 +106,10 @@ async function runWorker(stream, workerOptions) {
106
106
 
107
107
  function onTaskFinished(workerData) {
108
108
  clearStarvationTimeout();
109
- if (pendingRequests.length) {
109
+ if (workerData.terminated) {
110
+ workerData.terminated = false;
111
+ return runPendingRequestsInline();
112
+ } else if (pendingRequests.length) {
110
113
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
111
114
  resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
112
115
  armStarvationTimeout();
@@ -144,12 +147,26 @@ function onWorkerStarvation() {
144
147
  starvationTimeout = null;
145
148
  if (pendingRequests.length) {
146
149
  const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
147
- const inlineWorkerOptions = Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
148
- resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
150
+ resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), onInlineTaskFinished));
149
151
  armStarvationTimeout();
150
152
  }
151
153
  }
152
154
 
155
+ function runPendingRequestsInline() {
156
+ const tasks = pendingRequests.splice(0).map(({ resolve, stream, workerOptions }) => new Promise(resolveTask => {
157
+ resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), () => {
158
+ onInlineTaskFinished();
159
+ resolveTask();
160
+ }));
161
+ }));
162
+ clearStarvationTimeout();
163
+ return Promise.all(tasks);
164
+ }
165
+
166
+ function getInlineWorkerOptions(workerOptions) {
167
+ return Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
168
+ }
169
+
153
170
  function onInlineTaskFinished() {
154
171
  clearStarvationTimeout();
155
172
  armStarvationTimeout();
@@ -159,18 +176,14 @@ function terminateWorker(workerData, workerOptions) {
159
176
  const { config } = workerOptions;
160
177
  const { terminateWorkerTimeout } = config;
161
178
  if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
162
- if (workerData.terminated) {
163
- workerData.terminated = false;
164
- } else {
165
- workerData.terminateTimeout = setTimeout(async () => {
166
- pool = pool.filter(data => data != workerData);
167
- try {
168
- await workerData.terminate();
169
- } catch {
170
- // ignored
171
- }
172
- }, terminateWorkerTimeout);
173
- }
179
+ workerData.terminateTimeout = setTimeout(async () => {
180
+ pool = pool.filter(data => data != workerData);
181
+ try {
182
+ await workerData.terminate();
183
+ } catch {
184
+ // ignored
185
+ }
186
+ }, terminateWorkerTimeout);
174
187
  }
175
188
  }
176
189
 
@@ -183,9 +196,12 @@ function clearTerminateTimeout(workerData) {
183
196
  }
184
197
 
185
198
  async function terminateWorkers() {
186
- await Promise.allSettled(pool.map(workerData => {
187
- clearTerminateTimeout(workerData);
188
- return workerData.terminate();
189
- }));
199
+ await Promise.allSettled([
200
+ runPendingRequestsInline(),
201
+ ...pool.map(workerData => {
202
+ clearTerminateTimeout(workerData);
203
+ return workerData.terminate();
204
+ })
205
+ ]);
190
206
  resetWebWorkerSupport();
191
207
  }
@@ -133,7 +133,8 @@ class CodecWorker {
133
133
  return new Promise(resolve => {
134
134
  const { worker, busy } = workerData;
135
135
  if (busy) {
136
- workerData.resolveTerminated = resolve;
136
+ workerData.terminateResolvers = workerData.terminateResolvers || [];
137
+ workerData.terminateResolvers.push(resolve);
137
138
  } else {
138
139
  if (worker) {
139
140
  worker.terminate();
@@ -146,17 +147,19 @@ class CodecWorker {
146
147
  },
147
148
  onTaskFinished() {
148
149
  if (workerData.busy) {
149
- const { resolveTerminated, worker } = workerData;
150
- if (resolveTerminated) {
151
- workerData.resolveTerminated = null;
150
+ const { terminateResolvers, worker } = workerData;
151
+ if (terminateResolvers) {
152
+ workerData.terminateResolvers = null;
152
153
  if (worker) {
153
154
  workerData.terminated = true;
154
155
  worker.terminate();
155
156
  }
156
- resolveTerminated();
157
157
  }
158
158
  workerData.busy = false;
159
- onTaskFinished(workerData);
159
+ const pendingTasks = onTaskFinished(workerData);
160
+ if (terminateResolvers) {
161
+ terminateResolvers.forEach(resolve => resolve(pendingTasks));
162
+ }
160
163
  }
161
164
  }
162
165
  });
@@ -30,7 +30,7 @@ const BLOCK_LENGTH = 16;
30
30
  const ROUND_KEYS_LENGTH = 60;
31
31
  const SHA1_BLOCK_LENGTH = 64;
32
32
  const SHA1_DIGEST_LENGTH = 20;
33
- const SHA1_SCHEDULE_LENGTH = 80;
33
+ const SHA1_SCHEDULE_LENGTH = 16;
34
34
  const SHA1_LENGTH_OFFSET = 56;
35
35
  const SHA1_PADDING = new Uint8Array([0x80]);
36
36
  const SHA1_ZERO = new Uint8Array(1);
@@ -54,9 +54,12 @@ function createEngine(key, authenticationKey) {
54
54
  initTables();
55
55
  const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
56
56
  const rounds = expandKey(key, roundKeys);
57
- const counter = new Uint8Array(BLOCK_LENGTH);
58
57
  const keystream = new Int32Array(BLOCK_LENGTH / 4);
59
58
  const hmac = createHmac(authenticationKey);
59
+ let counter0 = 0;
60
+ let counter1 = 0;
61
+ let counter2 = 0;
62
+ let counter3 = 0;
60
63
  return {
61
64
  process(data, decrypt) {
62
65
  if (decrypt) {
@@ -92,31 +95,83 @@ function createEngine(key, authenticationKey) {
92
95
  }
93
96
 
94
97
  function nextKeystream() {
95
- for (let indexByte = 0; indexByte < BLOCK_LENGTH; indexByte++) {
96
- counter[indexByte]++;
97
- if (counter[indexByte] !== 0) {
98
- break;
98
+ counter0 = (counter0 + 1) | 0;
99
+ if (!counter0) {
100
+ counter1 = (counter1 + 1) | 0;
101
+ if (!counter1) {
102
+ counter2 = (counter2 + 1) | 0;
103
+ if (!counter2) {
104
+ counter3 = (counter3 + 1) | 0;
105
+ }
99
106
  }
100
107
  }
101
- let s0 = ((counter[0] << 24) | (counter[1] << 16) | (counter[2] << 8) | counter[3]) ^ roundKeys[0];
102
- let s1 = ((counter[4] << 24) | (counter[5] << 16) | (counter[6] << 8) | counter[7]) ^ roundKeys[1];
103
- let s2 = ((counter[8] << 24) | (counter[9] << 16) | (counter[10] << 8) | counter[11]) ^ roundKeys[2];
104
- let s3 = ((counter[12] << 24) | (counter[13] << 16) | (counter[14] << 8) | counter[15]) ^ roundKeys[3];
105
- let indexKey = 4;
106
- for (let round = 1; round < rounds; round++, indexKey += 4) {
107
- const t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[indexKey];
108
- const t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[indexKey + 1];
109
- const t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[indexKey + 2];
110
- const t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[indexKey + 3];
111
- s0 = t0;
112
- s1 = t1;
113
- s2 = t2;
114
- s3 = t3;
108
+ let s0 = swapBytes(counter0) ^ roundKeys[0];
109
+ let s1 = swapBytes(counter1) ^ roundKeys[1];
110
+ let s2 = swapBytes(counter2) ^ roundKeys[2];
111
+ let s3 = swapBytes(counter3) ^ roundKeys[3];
112
+ let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
113
+ let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
114
+ let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
115
+ let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
116
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
117
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
118
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
119
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
120
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
121
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
122
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
123
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
124
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
125
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
126
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
127
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
128
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
129
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
130
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
131
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
132
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
133
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
134
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
135
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
136
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
137
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
138
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
139
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
140
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
141
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
142
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
143
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
144
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
145
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
146
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
147
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
148
+ let indexKey = 40;
149
+ if (rounds > 10) {
150
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
151
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
152
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
153
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
154
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
155
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
156
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
157
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
158
+ indexKey = 48;
115
159
  }
116
- keystream[0] = ((S_BOX[s0 >>> 24] << 24) | (S_BOX[(s1 >>> 16) & 255] << 16) | (S_BOX[(s2 >>> 8) & 255] << 8) | S_BOX[s3 & 255]) ^ roundKeys[indexKey];
117
- keystream[1] = ((S_BOX[s1 >>> 24] << 24) | (S_BOX[(s2 >>> 16) & 255] << 16) | (S_BOX[(s3 >>> 8) & 255] << 8) | S_BOX[s0 & 255]) ^ roundKeys[indexKey + 1];
118
- keystream[2] = ((S_BOX[s2 >>> 24] << 24) | (S_BOX[(s3 >>> 16) & 255] << 16) | (S_BOX[(s0 >>> 8) & 255] << 8) | S_BOX[s1 & 255]) ^ roundKeys[indexKey + 2];
119
- keystream[3] = ((S_BOX[s3 >>> 24] << 24) | (S_BOX[(s0 >>> 16) & 255] << 16) | (S_BOX[(s1 >>> 8) & 255] << 8) | S_BOX[s2 & 255]) ^ roundKeys[indexKey + 3];
160
+ if (rounds > 12) {
161
+ s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
162
+ s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
163
+ s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
164
+ s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
165
+ t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
166
+ t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
167
+ t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
168
+ t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
169
+ indexKey = 56;
170
+ }
171
+ keystream[0] = ((S_BOX[t0 >>> 24] << 24) | (S_BOX[(t1 >>> 16) & 255] << 16) | (S_BOX[(t2 >>> 8) & 255] << 8) | S_BOX[t3 & 255]) ^ roundKeys[indexKey];
172
+ keystream[1] = ((S_BOX[t1 >>> 24] << 24) | (S_BOX[(t2 >>> 16) & 255] << 16) | (S_BOX[(t3 >>> 8) & 255] << 8) | S_BOX[t0 & 255]) ^ roundKeys[indexKey + 1];
173
+ keystream[2] = ((S_BOX[t2 >>> 24] << 24) | (S_BOX[(t3 >>> 16) & 255] << 16) | (S_BOX[(t0 >>> 8) & 255] << 8) | S_BOX[t1 & 255]) ^ roundKeys[indexKey + 2];
174
+ keystream[3] = ((S_BOX[t3 >>> 24] << 24) | (S_BOX[(t0 >>> 16) & 255] << 16) | (S_BOX[(t1 >>> 8) & 255] << 8) | S_BOX[t2 & 255]) ^ roundKeys[indexKey + 3];
120
175
  }
121
176
  }
122
177
 
@@ -240,47 +295,126 @@ function createSha1() {
240
295
  for (let index = 0; index < 16; index++) {
241
296
  schedule[index] = view.getInt32(offset + 4 * index);
242
297
  }
243
- for (let index = 16; index < SHA1_SCHEDULE_LENGTH; index++) {
244
- const word = schedule[index - 3] ^ schedule[index - 8] ^ schedule[index - 14] ^ schedule[index - 16];
245
- schedule[index] = (word << 1) | (word >>> 31);
246
- }
247
298
  let a = state[0];
248
299
  let b = state[1];
249
300
  let c = state[2];
250
301
  let d = state[3];
251
302
  let e = state[4];
252
303
  let t;
253
- for (let index = 0; index < 20; index++) {
254
- t = (((a << 5) | (a >>> 27)) + ((b & c) | (~b & d)) + e + 0x5A827999 + schedule[index]) | 0;
255
- e = d;
256
- d = c;
257
- c = (b << 30) | (b >>> 2);
258
- b = a;
259
- a = t;
304
+ for (let index = 0; index < 15; index += 5) {
305
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
306
+ b = (b << 30) | (b >>> 2);
307
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
308
+ a = (a << 30) | (a >>> 2);
309
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
310
+ e = (e << 30) | (e >>> 2);
311
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
312
+ d = (d << 30) | (d >>> 2);
313
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
314
+ c = (c << 30) | (c >>> 2);
260
315
  }
261
- for (let index = 20; index < 40; index++) {
262
- t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + schedule[index]) | 0;
263
- e = d;
264
- d = c;
265
- c = (b << 30) | (b >>> 2);
266
- b = a;
267
- a = t;
316
+ e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
317
+ b = (b << 30) | (b >>> 2);
318
+ t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
319
+ t = (t << 1) | (t >>> 31);
320
+ schedule[0] = t;
321
+ d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
322
+ a = (a << 30) | (a >>> 2);
323
+ t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
324
+ t = (t << 1) | (t >>> 31);
325
+ schedule[1] = t;
326
+ c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
327
+ e = (e << 30) | (e >>> 2);
328
+ t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
329
+ t = (t << 1) | (t >>> 31);
330
+ schedule[2] = t;
331
+ b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
332
+ d = (d << 30) | (d >>> 2);
333
+ t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
334
+ t = (t << 1) | (t >>> 31);
335
+ schedule[3] = t;
336
+ a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
337
+ c = (c << 30) | (c >>> 2);
338
+ for (let index = 20; index < 40; index += 5) {
339
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
340
+ t = (t << 1) | (t >>> 31);
341
+ schedule[(index) & 15] = t;
342
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
343
+ b = (b << 30) | (b >>> 2);
344
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
345
+ t = (t << 1) | (t >>> 31);
346
+ schedule[(index + 1) & 15] = t;
347
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
348
+ a = (a << 30) | (a >>> 2);
349
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
350
+ t = (t << 1) | (t >>> 31);
351
+ schedule[(index + 2) & 15] = t;
352
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
353
+ e = (e << 30) | (e >>> 2);
354
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
355
+ t = (t << 1) | (t >>> 31);
356
+ schedule[(index + 3) & 15] = t;
357
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
358
+ d = (d << 30) | (d >>> 2);
359
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
360
+ t = (t << 1) | (t >>> 31);
361
+ schedule[(index + 4) & 15] = t;
362
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
363
+ c = (c << 30) | (c >>> 2);
268
364
  }
269
- for (let index = 40; index < 60; index++) {
270
- t = (((a << 5) | (a >>> 27)) + ((b & c) | (b & d) | (c & d)) + e + 0x8F1BBCDC + schedule[index]) | 0;
271
- e = d;
272
- d = c;
273
- c = (b << 30) | (b >>> 2);
274
- b = a;
275
- a = t;
365
+ for (let index = 40; index < 60; index += 5) {
366
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
367
+ t = (t << 1) | (t >>> 31);
368
+ schedule[(index) & 15] = t;
369
+ e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
370
+ b = (b << 30) | (b >>> 2);
371
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
372
+ t = (t << 1) | (t >>> 31);
373
+ schedule[(index + 1) & 15] = t;
374
+ d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
375
+ a = (a << 30) | (a >>> 2);
376
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
377
+ t = (t << 1) | (t >>> 31);
378
+ schedule[(index + 2) & 15] = t;
379
+ c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
380
+ e = (e << 30) | (e >>> 2);
381
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
382
+ t = (t << 1) | (t >>> 31);
383
+ schedule[(index + 3) & 15] = t;
384
+ b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
385
+ d = (d << 30) | (d >>> 2);
386
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
387
+ t = (t << 1) | (t >>> 31);
388
+ schedule[(index + 4) & 15] = t;
389
+ a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
390
+ c = (c << 30) | (c >>> 2);
276
391
  }
277
- for (let index = 60; index < SHA1_SCHEDULE_LENGTH; index++) {
278
- t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + schedule[index]) | 0;
279
- e = d;
280
- d = c;
281
- c = (b << 30) | (b >>> 2);
282
- b = a;
283
- a = t;
392
+ for (let index = 60; index < 80; index += 5) {
393
+ t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
394
+ t = (t << 1) | (t >>> 31);
395
+ schedule[(index) & 15] = t;
396
+ e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
397
+ b = (b << 30) | (b >>> 2);
398
+ t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
399
+ t = (t << 1) | (t >>> 31);
400
+ schedule[(index + 1) & 15] = t;
401
+ d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
402
+ a = (a << 30) | (a >>> 2);
403
+ t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
404
+ t = (t << 1) | (t >>> 31);
405
+ schedule[(index + 2) & 15] = t;
406
+ c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
407
+ e = (e << 30) | (e >>> 2);
408
+ t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
409
+ t = (t << 1) | (t >>> 31);
410
+ schedule[(index + 3) & 15] = t;
411
+ b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
412
+ d = (d << 30) | (d >>> 2);
413
+ t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
414
+ t = (t << 1) | (t >>> 31);
415
+ schedule[(index + 4) & 15] = t;
416
+ a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
417
+ c = (c << 30) | (c >>> 2);
284
418
  }
285
419
  state[0] = (state[0] + a) | 0;
286
420
  state[1] = (state[1] + b) | 0;
@@ -343,6 +477,10 @@ function substituteWord(word) {
343
477
  return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
344
478
  }
345
479
 
480
+ function swapBytes(value) {
481
+ return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
482
+ }
483
+
346
484
  function multiplyByTwo(value) {
347
485
  return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
348
486
  }
@@ -70,8 +70,8 @@ class DeflateStream extends TransformStream {
70
70
  let crc32Stream, encryptionStream, gzipCrc32Stream;
71
71
  let readable = super.readable;
72
72
  const codecStreams = format && getCodecStreams(format);
73
- const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
74
- Boolean(useCompressionStream && CompressionStream);
73
+ const GzipCompressionStream = getGzipCompressionStream(useCompressionStream, CompressionStream, CompressionStreamFallback);
74
+ const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) && Boolean(GzipCompressionStream);
75
75
  if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
76
76
  crc32Stream = new Crc32Stream();
77
77
  readable = pipeThrough(readable, crc32Stream);
@@ -81,7 +81,7 @@ class DeflateStream extends TransformStream {
81
81
  readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod, uncompressedSize: inputSize }));
82
82
  } else if (useGzipCrc32) {
83
83
  gzipCrc32Stream = new GzipToRawDeflateStream();
84
- readable = pipeThroughBackpressured(readable, new CompressionStream(FORMAT_GZIP));
84
+ readable = pipeThroughBackpressured(readable, new GzipCompressionStream(FORMAT_GZIP, { level, chunkSize }));
85
85
  readable = pipeThrough(readable, gzipCrc32Stream);
86
86
  } else {
87
87
  try {
@@ -155,8 +155,7 @@ class GzipToRawDeflateStream extends TransformStream {
155
155
  }
156
156
  }
157
157
 
158
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
159
- const crc32 = new Crc32();
158
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
160
159
  let outputLength = 0;
161
160
  let inputDone = false;
162
161
  let watchdogTimeout;
@@ -230,7 +229,7 @@ class InflateStream extends TransformStream {
230
229
  constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
231
230
  super({});
232
231
  const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
233
- let crc32Stream, decryptionStream;
232
+ let crc32Stream, decryptionStream, gzipCrc32;
234
233
  let readable = super.readable;
235
234
  if (encrypted) {
236
235
  if (zipCrypto) {
@@ -257,19 +256,20 @@ class InflateStream extends TransformStream {
257
256
  } catch {
258
257
  throw error;
259
258
  }
260
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize);
259
+ gzipCrc32 = new Crc32();
260
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, gzipCrc32);
261
261
  }
262
262
  }
263
263
  readable = mapInflateStreamError(readable);
264
264
  }
265
- if (checkCrc32) {
265
+ if (checkCrc32 && !gzipCrc32) {
266
266
  crc32Stream = new Crc32Stream();
267
267
  readable = pipeThrough(readable, crc32Stream);
268
268
  }
269
269
  setReadable(this, readable, () => {
270
270
  if (checkCrc32) {
271
- const computedCrc32View = new DataView(crc32Stream.value.buffer);
272
- if (crc32 != computedCrc32View.getUint32(0, false)) {
271
+ const computedCrc32 = gzipCrc32 ? gzipCrc32.get() >>> 0 : new DataView(crc32Stream.value.buffer).getUint32(0, false);
272
+ if (crc32 != computedCrc32) {
273
273
  throw new Error(ERR_INVALID_CRC32);
274
274
  }
275
275
  }
@@ -343,6 +343,14 @@ function createCodecStream(CodecStreamClass, format, options) {
343
343
  return new CodecStreamClass(format, options);
344
344
  }
345
345
 
346
+ function getGzipCompressionStream(useCompressionStream, CompressionStreamNative, CompressionStreamFallback) {
347
+ if (useCompressionStream && CompressionStreamNative) {
348
+ return CompressionStreamNative;
349
+ } else if (CompressionStreamFallback && CompressionStreamFallback.requiresModule) {
350
+ return CompressionStreamFallback;
351
+ }
352
+ }
353
+
346
354
  function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
347
355
  const Stream = useCompressionStream && CompressionStreamNative ?
348
356
  CompressionStreamNative :
@@ -72,7 +72,6 @@ function _make(isCompress, type, options = {}) {
72
72
  if (!this.out || !this.in) {
73
73
  throw new Error("allocation failed");
74
74
  }
75
- this._scratch = new Uint8Array(outBufferSize);
76
75
  if (isCompress) {
77
76
  this._process = wasm.deflate_process;
78
77
  this._last_consumed = wasm.deflate_last_consumed;
@@ -121,7 +120,6 @@ function _make(isCompress, type, options = {}) {
121
120
  const process = this._process;
122
121
  const last_consumed = this._last_consumed;
123
122
  const out = this.out;
124
- const scratch = this._scratch;
125
123
  let offset = 0;
126
124
  while (offset < buffer.length) {
127
125
  const toRead = Math.min(buffer.length - offset, 32 * 1024);
@@ -146,8 +144,7 @@ function _make(isCompress, type, options = {}) {
146
144
  }
147
145
  const prod = result & 0x00ffffff;
148
146
  if (prod) {
149
- scratch.set(heap.subarray(out, out + prod), 0);
150
- controller.enqueue(scratch.slice(0, prod));
147
+ controller.enqueue(heap.slice(out, out + prod));
151
148
  }
152
149
  const consumed = last_consumed(this.streamHandle);
153
150
  if (consumed === 0 && prod === 0) {
@@ -165,7 +162,6 @@ function _make(isCompress, type, options = {}) {
165
162
  const heap = new Uint8Array(memory.buffer);
166
163
  const process = this._process;
167
164
  const out = this.out;
168
- const scratch = this._scratch;
169
165
  while (true) {
170
166
  const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
171
167
  const code = (result >> 24) & 0xff;
@@ -175,8 +171,7 @@ function _make(isCompress, type, options = {}) {
175
171
  }
176
172
  const produced = result & 0x00ffffff;
177
173
  if (produced) {
178
- scratch.set(heap.subarray(out, out + produced), 0);
179
- controller.enqueue(scratch.slice(0, produced));
174
+ controller.enqueue(heap.slice(out, out + produced));
180
175
  }
181
176
  if (code === 1 || produced === 0) {
182
177
  break;
@@ -32,13 +32,27 @@ import { decodeCP437 } from "./decode-cp437.js";
32
32
 
33
33
  export {
34
34
  decodeText,
35
- decodeTextRemovingBOM
35
+ decodeTextRemovingBOM,
36
+ isUTF8Text
36
37
  };
37
38
 
38
39
  function decodeText(value, encoding) {
39
40
  return decode(value, encoding, true);
40
41
  }
41
42
 
43
+ function isUTF8Text(value) {
44
+ if (value.some(byte => byte > 0x7f)) {
45
+ try {
46
+ new TextDecoder("utf-8", { fatal: true }).decode(value);
47
+ return true;
48
+ } catch {
49
+ return false;
50
+ }
51
+ } else {
52
+ return false;
53
+ }
54
+ }
55
+
42
56
  function decodeTextRemovingBOM(value, encoding) {
43
57
  return decode(value, encoding, false);
44
58
  }
@@ -26,6 +26,6 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- const VERSION = "2.14.0";
29
+ const VERSION = "2.15.0";
30
30
 
31
31
  export { VERSION };