@zip.js/zip.js 2.5.3 → 2.5.7
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 +470 -499
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +470 -499
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +470 -499
- 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 +470 -499
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -3
- package/lib/core/{engine.js → codec-interface.js} +52 -50
- package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
- package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
- package/lib/core/configuration.js +10 -1
- package/lib/core/io.js +102 -100
- package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
- package/lib/core/{codecs → streams}/codec-stream.js +6 -6
- 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 +28 -32
- 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 -12
- package/lib/core/zip-writer.js +33 -25
- 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/lib/core/codecs/codec.js +0 -246
|
@@ -29,12 +29,12 @@
|
|
|
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;
|
|
36
36
|
|
|
37
|
-
class
|
|
37
|
+
class ZipCryptoDecryptionStream extends TransformStream {
|
|
38
38
|
|
|
39
39
|
constructor(password, passwordVerification) {
|
|
40
40
|
let stream;
|
|
@@ -47,18 +47,16 @@ class ZipCryptoDecryptStream 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;
|
|
@@ -68,7 +66,7 @@ class ZipCryptoDecryptStream extends TransformStream {
|
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
|
|
71
|
-
class
|
|
69
|
+
class ZipCryptoEncryptionStream extends TransformStream {
|
|
72
70
|
|
|
73
71
|
constructor(password, passwordVerification) {
|
|
74
72
|
super({
|
|
@@ -80,24 +78,22 @@ class ZipCryptoEncryptStream 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
|
}
|
|
@@ -106,8 +102,8 @@ class ZipCryptoEncryptStream extends TransformStream {
|
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
export {
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
ZipCryptoDecryptionStream,
|
|
106
|
+
ZipCryptoEncryptionStream,
|
|
111
107
|
ERR_INVALID_PASSWORD
|
|
112
108
|
};
|
|
113
109
|
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer in
|
|
12
|
+
the documentation and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
15
|
+
derived from this software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
18
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
20
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
23
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/* global CompressionStream, DecompressionStream, TransformStream */
|
|
30
|
+
|
|
31
|
+
import Crc32Stream from "./crc32-stream.js";
|
|
32
|
+
import {
|
|
33
|
+
AESEncryptionStream,
|
|
34
|
+
AESDecryptionStream
|
|
35
|
+
} from "./aes-crypto-stream.js";
|
|
36
|
+
import {
|
|
37
|
+
ZipCryptoEncryptionStream,
|
|
38
|
+
ZipCryptoDecryptionStream,
|
|
39
|
+
ERR_INVALID_PASSWORD
|
|
40
|
+
} from "./zip-crypto-stream.js";
|
|
41
|
+
import CodecStream from "./codec-stream.js";
|
|
42
|
+
|
|
43
|
+
const ERR_INVALID_SIGNATURE = "Invalid signature";
|
|
44
|
+
const COMPRESSION_FORMAT = "deflate-raw";
|
|
45
|
+
const UNDEFINED_TYPE = "undefined";
|
|
46
|
+
const COMPRESSION_STREAM_API_SUPPORTED = typeof CompressionStream == UNDEFINED_TYPE;
|
|
47
|
+
const DECOMPRESSION_STREAM_API_SUPPORTED = typeof DecompressionStream == UNDEFINED_TYPE;
|
|
48
|
+
let INFLATE_RAW_SUPPORTED = true;
|
|
49
|
+
let DEFLATE_RAW_SUPPORTED = true;
|
|
50
|
+
|
|
51
|
+
class DeflateStream extends TransformStream {
|
|
52
|
+
|
|
53
|
+
constructor(codecConstructor, options, { chunkSize }, ...strategies) {
|
|
54
|
+
super({}, ...strategies);
|
|
55
|
+
const { compressed, useCompressionStream, password, passwordVerification, encryptionStrength, zipCrypto, signed } = options;
|
|
56
|
+
const stream = this;
|
|
57
|
+
let crc32Stream, encryptionStream;
|
|
58
|
+
let readable = filterEmptyChunks(super.readable);
|
|
59
|
+
const encrypted = Boolean(password);
|
|
60
|
+
if ((!encrypted || zipCrypto) && signed) {
|
|
61
|
+
[readable, crc32Stream] = readable.tee();
|
|
62
|
+
crc32Stream = crc32Stream.pipeThrough(new Crc32Stream());
|
|
63
|
+
}
|
|
64
|
+
if (compressed) {
|
|
65
|
+
if ((useCompressionStream !== undefined && !useCompressionStream) || (COMPRESSION_STREAM_API_SUPPORTED && !DEFLATE_RAW_SUPPORTED)) {
|
|
66
|
+
readable = pipeCodecStream(codecConstructor, readable, chunkSize);
|
|
67
|
+
} else {
|
|
68
|
+
try {
|
|
69
|
+
const compressionStream = new CompressionStream(COMPRESSION_FORMAT);
|
|
70
|
+
readable = readable.pipeThrough(compressionStream);
|
|
71
|
+
} catch (_error) {
|
|
72
|
+
DEFLATE_RAW_SUPPORTED = false;
|
|
73
|
+
readable = pipeCodecStream(codecConstructor, readable, chunkSize);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (encrypted) {
|
|
78
|
+
if (zipCrypto) {
|
|
79
|
+
readable = readable.pipeThrough(new ZipCryptoEncryptionStream(password, passwordVerification));
|
|
80
|
+
} else {
|
|
81
|
+
encryptionStream = new AESEncryptionStream(password, encryptionStrength);
|
|
82
|
+
readable = readable.pipeThrough(encryptionStream);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
setReadable(stream, readable, async () => {
|
|
86
|
+
let signature;
|
|
87
|
+
if (encrypted && !zipCrypto) {
|
|
88
|
+
signature = encryptionStream.signature;
|
|
89
|
+
}
|
|
90
|
+
if ((!encrypted || zipCrypto) && signed) {
|
|
91
|
+
signature = await crc32Stream.getReader().read();
|
|
92
|
+
signature = new DataView(signature.value.buffer).getUint32(0);
|
|
93
|
+
}
|
|
94
|
+
stream.signature = signature;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class InflateStream extends TransformStream {
|
|
100
|
+
|
|
101
|
+
constructor(codecConstructor, options, { chunkSize }, ...strategies) {
|
|
102
|
+
super({}, ...strategies);
|
|
103
|
+
const { zipCrypto, password, passwordVerification, signed, encryptionStrength, compressed, useCompressionStream } = options;
|
|
104
|
+
const stream = this;
|
|
105
|
+
let crc32Stream, decryptionStream;
|
|
106
|
+
let readable = filterEmptyChunks(super.readable);
|
|
107
|
+
const encrypted = Boolean(password);
|
|
108
|
+
if (encrypted) {
|
|
109
|
+
if (zipCrypto) {
|
|
110
|
+
readable = readable.pipeThrough(new ZipCryptoDecryptionStream(password, passwordVerification));
|
|
111
|
+
} else {
|
|
112
|
+
decryptionStream = new AESDecryptionStream(password, signed, encryptionStrength);
|
|
113
|
+
readable = readable.pipeThrough(decryptionStream);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (compressed) {
|
|
117
|
+
if ((useCompressionStream !== undefined && !useCompressionStream) || (DECOMPRESSION_STREAM_API_SUPPORTED && !INFLATE_RAW_SUPPORTED)) {
|
|
118
|
+
readable = pipeCodecStream(codecConstructor, readable, chunkSize);
|
|
119
|
+
} else {
|
|
120
|
+
try {
|
|
121
|
+
readable = readable.pipeThrough(new DecompressionStream(COMPRESSION_FORMAT));
|
|
122
|
+
} catch (_error) {
|
|
123
|
+
INFLATE_RAW_SUPPORTED = false;
|
|
124
|
+
readable = pipeCodecStream(codecConstructor, readable, chunkSize);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if ((!encrypted || zipCrypto) && signed) {
|
|
129
|
+
[readable, crc32Stream] = readable.tee();
|
|
130
|
+
crc32Stream = crc32Stream.pipeThrough(new Crc32Stream());
|
|
131
|
+
}
|
|
132
|
+
setReadable(stream, readable, async () => {
|
|
133
|
+
if (encrypted && !zipCrypto) {
|
|
134
|
+
if (!decryptionStream.valid) {
|
|
135
|
+
throw new Error(ERR_INVALID_SIGNATURE);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if ((!encrypted || zipCrypto) && signed) {
|
|
139
|
+
const signature = await crc32Stream.getReader().read();
|
|
140
|
+
const dataViewSignature = new DataView(signature.value.buffer);
|
|
141
|
+
if (signature != dataViewSignature.getUint32(0, false)) {
|
|
142
|
+
throw new Error(ERR_INVALID_SIGNATURE);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
DeflateStream,
|
|
151
|
+
InflateStream,
|
|
152
|
+
ERR_INVALID_PASSWORD,
|
|
153
|
+
ERR_INVALID_SIGNATURE
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
function pipeCodecStream(codecConstructor, stream, chunkSize) {
|
|
157
|
+
return stream.pipeThrough(new CodecStream(codecConstructor, { chunkSize }));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function filterEmptyChunks(readable) {
|
|
161
|
+
return readable.pipeThrough(new TransformStream({
|
|
162
|
+
transform(chunk, controller) {
|
|
163
|
+
if (chunk && chunk.length) {
|
|
164
|
+
controller.enqueue(chunk);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function setReadable(stream, readable, flush) {
|
|
171
|
+
stream.length = 0;
|
|
172
|
+
readable = readable.pipeThrough(new TransformStream({
|
|
173
|
+
transform(chunk, controller) {
|
|
174
|
+
if (chunk && chunk.length) {
|
|
175
|
+
stream.length += chunk.length;
|
|
176
|
+
controller.enqueue(chunk);
|
|
177
|
+
}
|
|
178
|
+
}, flush
|
|
179
|
+
}));
|
|
180
|
+
Object.defineProperty(stream, "readable", {
|
|
181
|
+
get() {
|
|
182
|
+
return readable;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global self, importScripts, addEventListener, postMessage */
|
|
29
|
+
/* global self, importScripts, addEventListener, postMessage, ReadableStream, WritableStream */
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
createCodec,
|
|
@@ -37,7 +37,8 @@ import {
|
|
|
37
37
|
MESSAGE_PULL,
|
|
38
38
|
MESSAGE_DATA,
|
|
39
39
|
MESSAGE_ABORT,
|
|
40
|
-
|
|
40
|
+
MESSAGE_CLOSE
|
|
41
|
+
} from "./codec-interface.js";
|
|
41
42
|
|
|
42
43
|
const pendingMessages = new Map();
|
|
43
44
|
let codec;
|
|
@@ -78,16 +79,30 @@ async function init(message) {
|
|
|
78
79
|
} else if (options.codecType.startsWith(CODEC_INFLATE)) {
|
|
79
80
|
codecConstructor = self.Inflate;
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
const readable = new ReadableStream({
|
|
83
|
+
async pull(controller) {
|
|
84
|
+
let result = new Promise((resolve, reject) => pendingMessages.set(messageId, { resolve, reject }));
|
|
85
|
+
sendMessage({ type: MESSAGE_PULL, messageId });
|
|
86
|
+
messageId++;
|
|
87
|
+
const { value, done } = await result;
|
|
88
|
+
// debugger;
|
|
89
|
+
controller.enqueue(value);
|
|
90
|
+
if (done) {
|
|
91
|
+
controller.close();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, {
|
|
95
|
+
highWaterMark: 1
|
|
96
|
+
});
|
|
97
|
+
const writable = new WritableStream({
|
|
98
|
+
write(data) {
|
|
99
|
+
sendMessage({ type: MESSAGE_DATA, data });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
codec = createCodec(codecConstructor, readable, writable, options, message.config);
|
|
103
|
+
const result = await codec.run();
|
|
104
|
+
sendMessage({ type: MESSAGE_CLOSE, result });
|
|
105
|
+
|
|
91
106
|
} catch (error) {
|
|
92
107
|
postMessage({ error: { message: error.message, stack: error.stack } });
|
|
93
108
|
}
|
|
@@ -95,11 +110,11 @@ async function init(message) {
|
|
|
95
110
|
|
|
96
111
|
function sendMessage(message) {
|
|
97
112
|
if (message.data) {
|
|
98
|
-
const data = message.data
|
|
113
|
+
const data = message.data;
|
|
99
114
|
if (data && data.length) {
|
|
100
115
|
try {
|
|
101
|
-
message.data
|
|
102
|
-
postMessage(message, [message.data
|
|
116
|
+
message.data = data.buffer;
|
|
117
|
+
postMessage(message, [message.data]);
|
|
103
118
|
} catch (_error) {
|
|
104
119
|
postMessage(message);
|
|
105
120
|
}
|
package/lib/core/zip-fs-core.js
CHANGED
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
export { ERR_ABORT } from "./engine.js";
|
|
30
29
|
import {
|
|
31
30
|
Reader,
|
|
32
31
|
TextReader,
|
|
@@ -419,6 +418,7 @@ class FS {
|
|
|
419
418
|
}
|
|
420
419
|
|
|
421
420
|
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
421
|
+
export { ERR_ABORT } from "./codec-pool.js";
|
|
422
422
|
export { fs };
|
|
423
423
|
|
|
424
424
|
function getTotalSize(entries, propertyName) {
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -56,11 +56,18 @@ import {
|
|
|
56
56
|
FILE_ATTR_MSDOS_DIR_MASK,
|
|
57
57
|
DIRECTORY_SIGNATURE
|
|
58
58
|
} from "./constants.js";
|
|
59
|
-
import {
|
|
60
|
-
|
|
59
|
+
import {
|
|
60
|
+
getConfiguration,
|
|
61
|
+
getChunkSize
|
|
62
|
+
} from "./configuration.js";
|
|
63
|
+
import {
|
|
64
|
+
runCodec,
|
|
65
|
+
CODEC_INFLATE,
|
|
66
|
+
ERR_INVALID_SIGNATURE,
|
|
67
|
+
ERR_INVALID_PASSWORD
|
|
68
|
+
} from "./codec-pool.js";
|
|
61
69
|
import decodeText from "./util/decode-text.js";
|
|
62
|
-
import Crc32 from "./codecs/crc32.js";
|
|
63
|
-
import { processData } from "./engine.js";
|
|
70
|
+
import Crc32 from "./streams/codecs/crc32.js";
|
|
64
71
|
import Entry from "./zip-entry.js";
|
|
65
72
|
|
|
66
73
|
const ERR_BAD_FORMAT = "File format is not recognized";
|
|
@@ -292,7 +299,15 @@ class ZipEntry {
|
|
|
292
299
|
throw new Error(ERR_ENCRYPTED);
|
|
293
300
|
}
|
|
294
301
|
}
|
|
295
|
-
const
|
|
302
|
+
const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
|
|
303
|
+
const size = () => compressedSize;
|
|
304
|
+
const readable = reader.getStream({ offset: dataOffset, size, chunkSize: getChunkSize(config) });
|
|
305
|
+
const writable = writer.getStream();
|
|
306
|
+
const signal = getOptionValue(zipEntry, options, "signal");
|
|
307
|
+
if (!writer.initialized) {
|
|
308
|
+
await writer.init();
|
|
309
|
+
}
|
|
310
|
+
await runCodec(config.Inflate, readable, writable, {
|
|
296
311
|
codecType: CODEC_INFLATE,
|
|
297
312
|
password,
|
|
298
313
|
zipCrypto,
|
|
@@ -304,13 +319,7 @@ class ZipEntry {
|
|
|
304
319
|
encrypted,
|
|
305
320
|
useWebWorkers: getOptionValue(zipEntry, options, "useWebWorkers"),
|
|
306
321
|
useCompressionStream: getOptionValue(zipEntry, options, "useCompressionStream")
|
|
307
|
-
}, config);
|
|
308
|
-
if (!writer.initialized) {
|
|
309
|
-
await writer.init();
|
|
310
|
-
}
|
|
311
|
-
const signal = getOptionValue(zipEntry, options, "signal");
|
|
312
|
-
const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
|
|
313
|
-
await processData(codec, reader, writer, dataOffset, () => compressedSize, config, { onprogress: options.onprogress, signal });
|
|
322
|
+
}, config, { signal, onprogress: options.onprogress, size });
|
|
314
323
|
return writer.getData();
|
|
315
324
|
}
|
|
316
325
|
}
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -59,11 +59,16 @@ import {
|
|
|
59
59
|
MIN_DATE,
|
|
60
60
|
MAX_DATE
|
|
61
61
|
} from "./constants.js";
|
|
62
|
-
import {
|
|
63
|
-
|
|
62
|
+
import {
|
|
63
|
+
getConfiguration,
|
|
64
|
+
getChunkSize
|
|
65
|
+
} from "./configuration.js";
|
|
66
|
+
import {
|
|
67
|
+
CODEC_DEFLATE,
|
|
68
|
+
runCodec
|
|
69
|
+
} from "./codec-pool.js";
|
|
64
70
|
import encodeText from "./util/encode-text.js";
|
|
65
71
|
import { BlobWriter } from "./io.js";
|
|
66
|
-
import { processData } from "./engine.js";
|
|
67
72
|
import Entry from "./zip-entry.js";
|
|
68
73
|
|
|
69
74
|
const ERR_DUPLICATED_NAME = "File already exists";
|
|
@@ -204,9 +209,6 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
204
209
|
}
|
|
205
210
|
let maximumCompressedSize = 0;
|
|
206
211
|
let keepOrder = getOptionValue(zipWriter, options, "keepOrder");
|
|
207
|
-
if (keepOrder === undefined) {
|
|
208
|
-
keepOrder = true;
|
|
209
|
-
}
|
|
210
212
|
let uncompressedSize = 0;
|
|
211
213
|
let msDosCompatible = getOptionValue(zipWriter, options, "msDosCompatible");
|
|
212
214
|
if (msDosCompatible === undefined) {
|
|
@@ -280,8 +282,8 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
async function getFileEntry(zipWriter, name, reader, options) {
|
|
283
|
-
const files = zipWriter
|
|
284
|
-
const
|
|
285
|
+
const { files, writer } = zipWriter;
|
|
286
|
+
const streamWriter = writer.getStream().getWriter();
|
|
285
287
|
const previousFileEntry = Array.from(files.values()).pop();
|
|
286
288
|
let fileEntry = {};
|
|
287
289
|
let bufferedWrite;
|
|
@@ -307,7 +309,7 @@ async function getFileEntry(zipWriter, name, reader, options) {
|
|
|
307
309
|
}
|
|
308
310
|
fileWriter = writer;
|
|
309
311
|
}
|
|
310
|
-
fileEntry = await createFileEntry(reader, fileWriter, zipWriter.config, options);
|
|
312
|
+
fileEntry = await createFileEntry(reader, fileWriter.getStream(), fileWriter.getStream().getWriter(), zipWriter.config, options);
|
|
311
313
|
fileEntry.lock = lockCurrentFileEntry;
|
|
312
314
|
files.set(name, fileEntry);
|
|
313
315
|
fileEntry.filename = name;
|
|
@@ -337,10 +339,10 @@ async function getFileEntry(zipWriter, name, reader, options) {
|
|
|
337
339
|
setUint32(arrayBufferView, 18, fileEntry.compressedSize);
|
|
338
340
|
setUint32(arrayBufferView, 22, fileEntry.uncompressedSize);
|
|
339
341
|
}
|
|
340
|
-
await
|
|
342
|
+
await writeUint8Array(streamWriter, new Uint8Array(arrayBuffer));
|
|
341
343
|
indexWrittenData = headerLength;
|
|
342
344
|
}
|
|
343
|
-
await writeBlob(
|
|
345
|
+
await writeBlob(streamWriter, blob, indexWrittenData);
|
|
344
346
|
delete fileEntry.writingBufferedData;
|
|
345
347
|
}
|
|
346
348
|
fileEntry.offset = zipWriter.offset;
|
|
@@ -369,7 +371,7 @@ async function getFileEntry(zipWriter, name, reader, options) {
|
|
|
369
371
|
}
|
|
370
372
|
}
|
|
371
373
|
|
|
372
|
-
async function createFileEntry(reader,
|
|
374
|
+
async function createFileEntry(reader, writable, streamWriter, config, options) {
|
|
373
375
|
const {
|
|
374
376
|
rawFilename,
|
|
375
377
|
lastAccessDate,
|
|
@@ -516,7 +518,11 @@ async function createFileEntry(reader, writer, config, options) {
|
|
|
516
518
|
let result;
|
|
517
519
|
let compressedSize = 0;
|
|
518
520
|
if (reader) {
|
|
519
|
-
|
|
521
|
+
await writeUint8Array(streamWriter, localHeaderArray);
|
|
522
|
+
fileEntry.dataWritten = true;
|
|
523
|
+
const size = () => reader.size;
|
|
524
|
+
const readable = reader.getStream({ offset: 0, size, chunkSize: getChunkSize(config) });
|
|
525
|
+
result = await runCodec(config.Deflate, readable, writable, {
|
|
520
526
|
codecType: CODEC_DEFLATE,
|
|
521
527
|
level,
|
|
522
528
|
password,
|
|
@@ -528,14 +534,11 @@ async function createFileEntry(reader, writer, config, options) {
|
|
|
528
534
|
encrypted,
|
|
529
535
|
useWebWorkers,
|
|
530
536
|
useCompressionStream
|
|
531
|
-
}, config);
|
|
532
|
-
await writer.writeUint8Array(localHeaderArray);
|
|
533
|
-
fileEntry.dataWritten = true;
|
|
534
|
-
result = await processData(codec, reader, writer, 0, () => reader.size, config, { onprogress, signal });
|
|
537
|
+
}, config, { signal, onprogress, size });
|
|
535
538
|
uncompressedSize = fileEntry.uncompressedSize = reader.size;
|
|
536
539
|
compressedSize = result.length;
|
|
537
540
|
} else {
|
|
538
|
-
await
|
|
541
|
+
await writeUint8Array(streamWriter, localHeaderArray);
|
|
539
542
|
fileEntry.dataWritten = true;
|
|
540
543
|
}
|
|
541
544
|
let dataDescriptorArray = new Uint8Array(0);
|
|
@@ -579,7 +582,7 @@ async function createFileEntry(reader, writer, config, options) {
|
|
|
579
582
|
}
|
|
580
583
|
}
|
|
581
584
|
if (dataDescriptor) {
|
|
582
|
-
await
|
|
585
|
+
await writeUint8Array(streamWriter, dataDescriptorArray);
|
|
583
586
|
}
|
|
584
587
|
const length = localHeaderArray.length + compressedSize + dataDescriptorArray.length;
|
|
585
588
|
Object.assign(fileEntry, { compressedSize, lastModDate, rawLastModDate, creationDate, lastAccessDate, encrypted, length });
|
|
@@ -587,8 +590,8 @@ async function createFileEntry(reader, writer, config, options) {
|
|
|
587
590
|
}
|
|
588
591
|
|
|
589
592
|
async function closeFile(zipWriter, comment, options) {
|
|
590
|
-
const
|
|
591
|
-
const
|
|
593
|
+
const { files } = zipWriter;
|
|
594
|
+
const streamWriter = zipWriter.writer.getStream().getWriter();
|
|
592
595
|
let offset = 0;
|
|
593
596
|
let directoryDataLength = 0;
|
|
594
597
|
let directoryOffset = zipWriter.offset;
|
|
@@ -703,9 +706,9 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
703
706
|
setUint16(directoryView, offset + 10, filesLength);
|
|
704
707
|
setUint32(directoryView, offset + 12, directoryDataLength);
|
|
705
708
|
setUint32(directoryView, offset + 16, directoryOffset);
|
|
706
|
-
await
|
|
709
|
+
await writeUint8Array(streamWriter, directoryArray);
|
|
707
710
|
if (comment && comment.length) {
|
|
708
|
-
await
|
|
711
|
+
await writeUint8Array(streamWriter, comment);
|
|
709
712
|
}
|
|
710
713
|
}
|
|
711
714
|
|
|
@@ -726,20 +729,25 @@ function sliceAsArrayBuffer(blob, start, end) {
|
|
|
726
729
|
}
|
|
727
730
|
}
|
|
728
731
|
|
|
729
|
-
async function writeBlob(
|
|
732
|
+
async function writeBlob(streamWriter, blob, start = 0) {
|
|
730
733
|
const blockSize = 512 * 1024 * 1024;
|
|
731
734
|
await writeSlice();
|
|
732
735
|
|
|
733
736
|
async function writeSlice() {
|
|
734
737
|
if (start < blob.size) {
|
|
735
738
|
const arrayBuffer = await sliceAsArrayBuffer(blob, start, start + blockSize);
|
|
736
|
-
await
|
|
739
|
+
await writeUint8Array(streamWriter, new Uint8Array(arrayBuffer));
|
|
737
740
|
start += blockSize;
|
|
738
741
|
await writeSlice();
|
|
739
742
|
}
|
|
740
743
|
}
|
|
741
744
|
}
|
|
742
745
|
|
|
746
|
+
async function writeUint8Array(streamWriter, array) {
|
|
747
|
+
await streamWriter.ready;
|
|
748
|
+
await streamWriter.write(array);
|
|
749
|
+
}
|
|
750
|
+
|
|
743
751
|
function getTimeNTFS(date) {
|
|
744
752
|
if (date) {
|
|
745
753
|
return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
|
package/lib/z-worker-fflate.js
CHANGED