@zip.js/zip.js 2.5.4 → 2.5.8
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.
- package/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +343 -408
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +343 -408
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +343 -408
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +343 -408
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +1 -1
- package/index.js +3 -3
- package/lib/core/{engine.js → codec-interface.js} +52 -46
- package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +60 -29
- package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
- package/lib/core/configuration.js +3 -0
- package/lib/core/io.js +13 -24
- package/lib/core/{codecs → streams}/aes-crypto-stream.js +35 -33
- package/lib/core/{codecs → streams}/codec-stream.js +7 -7
- package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
- package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
- package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
- package/lib/core/{codecs → streams}/zip-crypto-stream.js +24 -28
- package/lib/core/streams/zip-entry-stream.js +185 -0
- package/lib/core/z-worker-core.js +30 -15
- package/lib/core/zip-fs-core.js +1 -1
- package/lib/core/zip-reader.js +21 -18
- package/lib/core/zip-writer.js +30 -31
- package/lib/z-worker-fflate.js +4 -1
- package/lib/z-worker-inline.js +1 -1
- package/lib/z-worker.js +2 -2
- package/lib/zip-fflate-shim.js +4 -1
- package/lib/zip-fs.js +6 -2
- package/lib/zip-full-fflate.js +6 -3
- package/lib/zip-full.js +8 -5
- package/lib/zip-no-worker-deflate.js +7 -3
- package/lib/zip-no-worker-fflate-deflate.js +6 -2
- package/lib/zip-no-worker-fflate-inflate.js +6 -3
- package/lib/zip-no-worker-fflate.js +6 -3
- package/lib/zip-no-worker-inflate.js +7 -4
- package/lib/zip-no-worker.js +8 -5
- package/lib/zip.js +6 -3
- package/package.json +2 -8
- package/tests/all/test-parallel-writes-ordered.js +1 -1
- package/tests/all/test-readable-stream.js +2 -2
- package/tests/all/test-zip64-auto.js +1 -1
- package/lib/core/codecs/codec.js +0 -246
|
@@ -26,9 +26,17 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Worker, URL */
|
|
30
|
-
|
|
31
|
-
import {
|
|
29
|
+
/* global Worker, URL, TransformStream */
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
createCodec,
|
|
33
|
+
MESSAGE_EVENT_TYPE,
|
|
34
|
+
MESSAGE_START,
|
|
35
|
+
MESSAGE_PULL,
|
|
36
|
+
MESSAGE_DATA,
|
|
37
|
+
MESSAGE_ABORT,
|
|
38
|
+
MESSAGE_CLOSE
|
|
39
|
+
} from "./codec-interface.js";
|
|
32
40
|
|
|
33
41
|
let classicWorkersSupported = true;
|
|
34
42
|
|
|
@@ -36,10 +44,12 @@ export {
|
|
|
36
44
|
getWorker
|
|
37
45
|
};
|
|
38
46
|
|
|
39
|
-
function getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts) {
|
|
47
|
+
function getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts) {
|
|
40
48
|
Object.assign(workerData, {
|
|
41
49
|
busy: true,
|
|
42
50
|
codecConstructor,
|
|
51
|
+
readable,
|
|
52
|
+
writable,
|
|
43
53
|
options: Object.assign({}, options),
|
|
44
54
|
scripts,
|
|
45
55
|
terminate() {
|
|
@@ -53,27 +63,50 @@ function getWorker(workerData, codecConstructor, options, config, onTaskFinished
|
|
|
53
63
|
onTaskFinished(workerData);
|
|
54
64
|
}
|
|
55
65
|
});
|
|
66
|
+
const { signal, onprogress, size } = streamOptions;
|
|
67
|
+
if (signal || onprogress) {
|
|
68
|
+
let chunkOffset = 0;
|
|
69
|
+
const transformer = {};
|
|
70
|
+
if (onprogress) {
|
|
71
|
+
transformer.transform = (chunk, controller) => {
|
|
72
|
+
chunkOffset += chunk.length;
|
|
73
|
+
try {
|
|
74
|
+
onprogress(chunkOffset, size());
|
|
75
|
+
} catch (_error) {
|
|
76
|
+
// ignored
|
|
77
|
+
}
|
|
78
|
+
controller.enqueue(chunk);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
workerData.readable = readable.pipeThrough(new TransformStream(transformer), { signal });
|
|
82
|
+
}
|
|
56
83
|
return webWorker ? createWebWorkerInterface(workerData, config) : createWorkerInterface(workerData, config);
|
|
57
84
|
}
|
|
58
85
|
|
|
59
86
|
function createWorkerInterface(workerData, config) {
|
|
60
|
-
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.options, config);
|
|
87
|
+
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.readable, workerData.writable, workerData.options, config);
|
|
61
88
|
const codec = {
|
|
62
89
|
abort() {
|
|
63
90
|
interfaceCodec.abort();
|
|
64
91
|
workerData.onTaskFinished();
|
|
65
92
|
},
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
run() {
|
|
94
|
+
const result = interfaceCodec.run();
|
|
95
|
+
workerData.onTaskFinished();
|
|
96
|
+
return result;
|
|
68
97
|
}
|
|
69
98
|
};
|
|
70
|
-
interfaceCodec.pull = () => codec.pull();
|
|
71
|
-
interfaceCodec.ondata = data => ondata(workerData, codec, data);
|
|
72
99
|
return codec;
|
|
73
100
|
}
|
|
74
101
|
|
|
75
102
|
function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
76
103
|
const workerOptions = { type: "module" };
|
|
104
|
+
workerData.reader = workerData.readable.getReader();
|
|
105
|
+
workerData.writer = workerData.writable.getWriter();
|
|
106
|
+
workerData.result = new Promise((resolve, reject) => {
|
|
107
|
+
workerData.resolveResult = resolve;
|
|
108
|
+
workerData.rejectResult = reject;
|
|
109
|
+
});
|
|
77
110
|
if (!workerData.interface) {
|
|
78
111
|
if (!classicWorkersSupported) {
|
|
79
112
|
workerData.worker = getWorker(workerOptions);
|
|
@@ -89,12 +122,14 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
89
122
|
workerData.interface = {
|
|
90
123
|
abort() {
|
|
91
124
|
sendMessage({ type: MESSAGE_ABORT });
|
|
125
|
+
workerData.writer.releaseLock();
|
|
92
126
|
workerData.onTaskFinished();
|
|
93
127
|
},
|
|
94
|
-
|
|
128
|
+
run() {
|
|
95
129
|
const options = workerData.options;
|
|
96
130
|
const scripts = workerData.scripts.slice(1);
|
|
97
131
|
sendMessage({ type: MESSAGE_START, scripts, options, config: { chunkSize } });
|
|
132
|
+
return workerData.result;
|
|
98
133
|
}
|
|
99
134
|
};
|
|
100
135
|
}
|
|
@@ -128,6 +163,7 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
128
163
|
worker.postMessage(message);
|
|
129
164
|
}
|
|
130
165
|
} catch (error) {
|
|
166
|
+
workerData.writer.releaseLock();
|
|
131
167
|
workerData.onTaskFinished();
|
|
132
168
|
throw error;
|
|
133
169
|
}
|
|
@@ -136,39 +172,34 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
136
172
|
async function onMessage(event) {
|
|
137
173
|
const message = event.data;
|
|
138
174
|
const reponseError = message.error;
|
|
139
|
-
const codec = workerData.interface;
|
|
140
175
|
try {
|
|
141
176
|
if (reponseError) {
|
|
142
177
|
const error = new Error(reponseError.message);
|
|
143
178
|
error.stack = reponseError.stack;
|
|
144
|
-
|
|
179
|
+
workerData.rejectResult(error);
|
|
180
|
+
workerData.writer.releaseLock();
|
|
145
181
|
workerData.onTaskFinished();
|
|
146
182
|
} else {
|
|
147
183
|
if (message.type == MESSAGE_PULL) {
|
|
148
|
-
const { value, done } = await
|
|
184
|
+
const { value, done } = await workerData.reader.read();
|
|
149
185
|
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId: message.messageId });
|
|
150
186
|
}
|
|
151
187
|
if (message.type == MESSAGE_DATA) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
188
|
+
let { data } = message;
|
|
189
|
+
data = new Uint8Array(data);
|
|
190
|
+
await workerData.writer.ready;
|
|
191
|
+
await workerData.writer.write(data);
|
|
192
|
+
}
|
|
193
|
+
if (message.type == MESSAGE_CLOSE) {
|
|
194
|
+
workerData.resolveResult(message.result);
|
|
195
|
+
workerData.writer.releaseLock();
|
|
196
|
+
workerData.onTaskFinished();
|
|
157
197
|
}
|
|
158
198
|
}
|
|
159
199
|
} catch (error) {
|
|
160
|
-
|
|
200
|
+
workerData.rejectResult(error);
|
|
201
|
+
workerData.writer.releaseLock();
|
|
161
202
|
workerData.onTaskFinished();
|
|
162
203
|
}
|
|
163
204
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async function ondata(workerData, codec, data) {
|
|
167
|
-
let { value, done } = data;
|
|
168
|
-
if (done) {
|
|
169
|
-
await codec.ondata({ value: { data: value.data, signature: value.signature }, done });
|
|
170
|
-
workerData.onTaskFinished();
|
|
171
|
-
} else if (value.data) {
|
|
172
|
-
await codec.ondata({ value: { data: value.data } });
|
|
173
|
-
}
|
|
174
205
|
}
|
|
@@ -28,47 +28,66 @@
|
|
|
28
28
|
|
|
29
29
|
/* global setTimeout, clearTimeout */
|
|
30
30
|
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
CODEC_INFLATE,
|
|
33
|
+
CODEC_DEFLATE,
|
|
34
|
+
ERR_INVALID_SIGNATURE,
|
|
35
|
+
ERR_INVALID_PASSWORD,
|
|
36
|
+
ERR_ABORT
|
|
37
|
+
} from "./codec-interface.js";
|
|
32
38
|
import { getWorker } from "./codec-pool-worker.js";
|
|
33
39
|
|
|
34
40
|
let pool = [];
|
|
35
41
|
const pendingRequests = [];
|
|
36
42
|
|
|
37
43
|
export {
|
|
38
|
-
|
|
44
|
+
runCodec,
|
|
39
45
|
terminateWorkers,
|
|
40
46
|
CODEC_DEFLATE,
|
|
41
47
|
CODEC_INFLATE,
|
|
42
48
|
ERR_INVALID_SIGNATURE,
|
|
43
|
-
ERR_INVALID_PASSWORD
|
|
49
|
+
ERR_INVALID_PASSWORD,
|
|
50
|
+
ERR_ABORT
|
|
44
51
|
};
|
|
45
52
|
|
|
46
53
|
let indexWorker = 0;
|
|
47
54
|
|
|
48
|
-
function
|
|
55
|
+
async function runCodec(codecConstructor, readable, writable, options, config, streamOptions) {
|
|
49
56
|
const streamCopy = !options.compressed && !options.signed && !options.encrypted;
|
|
50
57
|
const webWorker = !streamCopy && (options.useWebWorkers || (options.useWebWorkers === undefined && config.useWebWorkers));
|
|
51
58
|
const scripts = webWorker && config.workerScripts ? config.workerScripts[options.codecType] : [];
|
|
52
59
|
options.useCompressionStream = options.useCompressionStream === undefined ? config.useCompressionStream : options.useCompressionStream;
|
|
60
|
+
let codec;
|
|
53
61
|
if (pool.length < config.maxWorkers) {
|
|
54
62
|
const workerData = { indexWorker };
|
|
55
63
|
indexWorker++;
|
|
56
64
|
pool.push(workerData);
|
|
57
|
-
|
|
65
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
58
66
|
} else {
|
|
59
67
|
const workerData = pool.find(workerData => !workerData.busy);
|
|
60
68
|
if (workerData) {
|
|
61
69
|
clearTerminateTimeout(workerData);
|
|
62
|
-
|
|
70
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
71
|
+
} else {
|
|
72
|
+
codec = await new Promise(resolve => pendingRequests.push({ resolve, codecConstructor, readable, writable, options, webWorker, scripts }));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const { signal } = streamOptions;
|
|
76
|
+
try {
|
|
77
|
+
return await codec.run(signal);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (signal && signal.aborted && (signal.reason == error || error.name == ERR_ABORT)) {
|
|
80
|
+
codec.abort();
|
|
81
|
+
throw new Error(ERR_ABORT);
|
|
63
82
|
} else {
|
|
64
|
-
|
|
83
|
+
throw error;
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
function onTaskFinished(workerData) {
|
|
69
88
|
if (pendingRequests.length) {
|
|
70
|
-
const [{ resolve, codecConstructor, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
71
|
-
resolve(getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts));
|
|
89
|
+
const [{ resolve, codecConstructor, readable, writable, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
90
|
+
resolve(getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts));
|
|
72
91
|
} else if (workerData.worker) {
|
|
73
92
|
clearTerminateTimeout(workerData);
|
|
74
93
|
if (Number.isFinite(config.terminateWorkerTimeout) && config.terminateWorkerTimeout >= 0) {
|
|
@@ -66,6 +66,9 @@ function configure(configuration) {
|
|
|
66
66
|
if (configuration.terminateWorkerTimeout !== undefined) {
|
|
67
67
|
config.terminateWorkerTimeout = configuration.terminateWorkerTimeout;
|
|
68
68
|
}
|
|
69
|
+
if (configuration.useCompressionStream !== undefined) {
|
|
70
|
+
config.useCompressionStream = configuration.useCompressionStream;
|
|
71
|
+
}
|
|
69
72
|
if (configuration.useWebWorkers !== undefined) {
|
|
70
73
|
config.useWebWorkers = configuration.useWebWorkers;
|
|
71
74
|
}
|
package/lib/core/io.js
CHANGED
|
@@ -75,24 +75,15 @@ class Reader extends Stream {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
class WriterStream extends Stream {
|
|
78
|
+
|
|
78
79
|
getStream() {
|
|
79
80
|
const writer = this;
|
|
80
81
|
return new WritableStream({
|
|
81
82
|
write(chunk) {
|
|
82
|
-
|
|
83
|
-
return writer.writeUint8Array(chunk);
|
|
84
|
-
}
|
|
83
|
+
return writer.writeUint8Array(chunk);
|
|
85
84
|
}
|
|
86
85
|
});
|
|
87
86
|
}
|
|
88
|
-
|
|
89
|
-
getStreamWriter() {
|
|
90
|
-
const writer = this;
|
|
91
|
-
if (!writer.streamWriter) {
|
|
92
|
-
writer.streamWriter = writer.getStream().getWriter();
|
|
93
|
-
}
|
|
94
|
-
return writer.streamWriter;
|
|
95
|
-
}
|
|
96
87
|
}
|
|
97
88
|
|
|
98
89
|
class Writer extends WriterStream {
|
|
@@ -275,13 +266,12 @@ function flushArrayBuffers(blobWriter) {
|
|
|
275
266
|
|
|
276
267
|
class ReadableStreamReader {
|
|
277
268
|
|
|
278
|
-
constructor(readableStream) {
|
|
269
|
+
constructor(readableStream, size = Infinity) {
|
|
279
270
|
this.readableStream = readableStream;
|
|
280
|
-
this.size =
|
|
271
|
+
this.size = size;
|
|
281
272
|
}
|
|
282
273
|
|
|
283
|
-
init(
|
|
284
|
-
this.size = size;
|
|
274
|
+
init() {
|
|
285
275
|
this.initialized = true;
|
|
286
276
|
}
|
|
287
277
|
|
|
@@ -292,27 +282,26 @@ class ReadableStreamReader {
|
|
|
292
282
|
|
|
293
283
|
class WritableStreamWriter extends Writer {
|
|
294
284
|
|
|
295
|
-
constructor(
|
|
285
|
+
constructor(writable) {
|
|
296
286
|
super();
|
|
297
287
|
const writer = this;
|
|
298
|
-
writer.
|
|
299
|
-
writer.writer = writer.getStreamWriter();
|
|
288
|
+
writer.writable = writable;
|
|
300
289
|
}
|
|
301
290
|
|
|
302
291
|
async writeUint8Array(array) {
|
|
303
292
|
await this.writer.ready;
|
|
304
|
-
|
|
293
|
+
const writer = this.writable.getWriter();
|
|
294
|
+
await writer.write(array);
|
|
295
|
+
writer.releaseLock();
|
|
305
296
|
}
|
|
306
297
|
|
|
307
298
|
getStream() {
|
|
308
|
-
return this.
|
|
299
|
+
return this.writable;
|
|
309
300
|
}
|
|
310
301
|
|
|
311
302
|
async getData() {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
await writer.writer.close();
|
|
315
|
-
return writer.writableStream;
|
|
303
|
+
await this.writable.getWriter().close();
|
|
304
|
+
return this.writable;
|
|
316
305
|
}
|
|
317
306
|
}
|
|
318
307
|
|
|
@@ -30,7 +30,13 @@
|
|
|
30
30
|
// deno-lint-ignore-file no-this-alias
|
|
31
31
|
|
|
32
32
|
import encodeText from "./../util/encode-text.js";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
cipher,
|
|
35
|
+
codec,
|
|
36
|
+
misc,
|
|
37
|
+
mode,
|
|
38
|
+
random
|
|
39
|
+
} from "./codecs/sjcl.js";
|
|
34
40
|
|
|
35
41
|
const ERR_INVALID_PASSWORD = "Invalid pasword";
|
|
36
42
|
const BLOCK_LENGTH = 16;
|
|
@@ -72,23 +78,21 @@ class AESDecryptionStream extends TransformStream {
|
|
|
72
78
|
});
|
|
73
79
|
},
|
|
74
80
|
async transform(chunk, controller) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
await aesCrypto.ready;
|
|
88
|
-
}
|
|
89
|
-
const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
|
|
90
|
-
controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
|
|
81
|
+
const aesCrypto = this;
|
|
82
|
+
if (aesCrypto.password) {
|
|
83
|
+
const password = aesCrypto.password;
|
|
84
|
+
aesCrypto.password = null;
|
|
85
|
+
const preamble = subarray(chunk, 0, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
86
|
+
await createDecryptionKeys(aesCrypto, preamble, password);
|
|
87
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
88
|
+
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
89
|
+
chunk = subarray(chunk, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
90
|
+
aesCrypto.resolveReady();
|
|
91
|
+
} else {
|
|
92
|
+
await aesCrypto.ready;
|
|
91
93
|
}
|
|
94
|
+
const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
|
|
95
|
+
controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
|
|
92
96
|
},
|
|
93
97
|
async flush(controller) {
|
|
94
98
|
const aesCrypto = this;
|
|
@@ -133,23 +137,21 @@ class AESEncryptionStream extends TransformStream {
|
|
|
133
137
|
});
|
|
134
138
|
},
|
|
135
139
|
async transform(chunk, controller) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
await aesCrypto.ready;
|
|
148
|
-
}
|
|
149
|
-
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
150
|
-
output.set(preamble, 0);
|
|
151
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
140
|
+
const aesCrypto = this;
|
|
141
|
+
let preamble = new Uint8Array(0);
|
|
142
|
+
if (aesCrypto.password) {
|
|
143
|
+
const password = aesCrypto.password;
|
|
144
|
+
aesCrypto.password = null;
|
|
145
|
+
preamble = await createEncryptionKeys(aesCrypto, password);
|
|
146
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
147
|
+
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
148
|
+
aesCrypto.resolveReady();
|
|
149
|
+
} else {
|
|
150
|
+
await aesCrypto.ready;
|
|
152
151
|
}
|
|
152
|
+
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
153
|
+
output.set(preamble, 0);
|
|
154
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
153
155
|
},
|
|
154
156
|
async flush(controller) {
|
|
155
157
|
const aesCrypto = this;
|
|
@@ -36,20 +36,20 @@
|
|
|
36
36
|
/* global TransformStream */
|
|
37
37
|
|
|
38
38
|
class CodecStream extends TransformStream {
|
|
39
|
+
|
|
39
40
|
constructor(Codec, options) {
|
|
41
|
+
let codec;
|
|
40
42
|
super({
|
|
41
43
|
start() {
|
|
42
|
-
|
|
44
|
+
codec = new Codec(options);
|
|
43
45
|
},
|
|
44
46
|
transform(chunk, controller) {
|
|
45
|
-
chunk =
|
|
46
|
-
|
|
47
|
-
controller.enqueue(chunk);
|
|
48
|
-
}
|
|
47
|
+
chunk = codec.append(chunk);
|
|
48
|
+
controller.enqueue(chunk);
|
|
49
49
|
},
|
|
50
50
|
flush(controller) {
|
|
51
|
-
const chunk =
|
|
52
|
-
if (chunk
|
|
51
|
+
const chunk = codec.flush();
|
|
52
|
+
if (chunk) {
|
|
53
53
|
controller.enqueue(chunk);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -28,18 +28,17 @@
|
|
|
28
28
|
|
|
29
29
|
/* global TransformStream */
|
|
30
30
|
|
|
31
|
-
import Crc32 from "./crc32.js";
|
|
31
|
+
import Crc32 from "./codecs/crc32.js";
|
|
32
32
|
|
|
33
33
|
class Crc32Stream extends TransformStream {
|
|
34
|
+
|
|
34
35
|
constructor() {
|
|
35
36
|
super({
|
|
36
37
|
start() {
|
|
37
38
|
this.crc32 = new Crc32();
|
|
38
39
|
},
|
|
39
40
|
transform(chunk) {
|
|
40
|
-
|
|
41
|
-
this.crc32.append(chunk);
|
|
42
|
-
}
|
|
41
|
+
this.crc32.append(chunk);
|
|
43
42
|
},
|
|
44
43
|
flush(controller) {
|
|
45
44
|
const value = new Uint8Array(4);
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
/* global crypto, TransformStream */
|
|
30
30
|
// deno-lint-ignore-file no-this-alias
|
|
31
31
|
|
|
32
|
-
import Crc32 from "./crc32.js";
|
|
32
|
+
import Crc32 from "./codecs/crc32.js";
|
|
33
33
|
import { ERR_INVALID_PASSWORD } from "./aes-crypto-stream.js";
|
|
34
34
|
|
|
35
35
|
const HEADER_LENGTH = 12;
|
|
@@ -47,18 +47,16 @@ class ZipCryptoDecryptionStream extends TransformStream {
|
|
|
47
47
|
createKeys(this, password);
|
|
48
48
|
},
|
|
49
49
|
transform(chunk, controller) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
throw new Error(ERR_INVALID_PASSWORD);
|
|
57
|
-
}
|
|
58
|
-
chunk = chunk.subarray(HEADER_LENGTH);
|
|
50
|
+
const zipCrypto = this;
|
|
51
|
+
if (zipCrypto.password) {
|
|
52
|
+
const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH));
|
|
53
|
+
zipCrypto.password = null;
|
|
54
|
+
if (decryptedHeader[HEADER_LENGTH - 1] != zipCrypto.passwordVerification) {
|
|
55
|
+
throw new Error(ERR_INVALID_PASSWORD);
|
|
59
56
|
}
|
|
60
|
-
|
|
57
|
+
chunk = chunk.subarray(HEADER_LENGTH);
|
|
61
58
|
}
|
|
59
|
+
controller.enqueue(decrypt(zipCrypto, chunk));
|
|
62
60
|
},
|
|
63
61
|
flush() {
|
|
64
62
|
stream.valid = true;
|
|
@@ -80,24 +78,22 @@ class ZipCryptoEncryptionStream extends TransformStream {
|
|
|
80
78
|
createKeys(this, password);
|
|
81
79
|
},
|
|
82
80
|
transform(chunk, controller) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
offset = 0;
|
|
97
|
-
}
|
|
98
|
-
output.set(encrypt(zipCrypto, chunk), offset);
|
|
99
|
-
controller.enqueue(output);
|
|
81
|
+
const zipCrypto = this;
|
|
82
|
+
let output;
|
|
83
|
+
let offset;
|
|
84
|
+
if (zipCrypto.password) {
|
|
85
|
+
zipCrypto.password = null;
|
|
86
|
+
const header = crypto.getRandomValues(new Uint8Array(HEADER_LENGTH));
|
|
87
|
+
header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification;
|
|
88
|
+
output = new Uint8Array(chunk.length + header.length);
|
|
89
|
+
output.set(encrypt(zipCrypto, header), 0);
|
|
90
|
+
offset = HEADER_LENGTH;
|
|
91
|
+
} else {
|
|
92
|
+
output = new Uint8Array(chunk.length);
|
|
93
|
+
offset = 0;
|
|
100
94
|
}
|
|
95
|
+
output.set(encrypt(zipCrypto, chunk), offset);
|
|
96
|
+
controller.enqueue(output);
|
|
101
97
|
},
|
|
102
98
|
flush() {
|
|
103
99
|
}
|