@zip.js/zip.js 2.6.26 → 2.6.29
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/README.md +1 -1
- 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 +1781 -1731
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +623 -573
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +623 -573
- 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 +583 -533
- package/dist/zip.min.js +1 -1
- package/index.cjs +10364 -0
- package/index.d.ts +42 -19
- package/lib/core/codec-interface.js +17 -9
- package/lib/core/codec-pool-worker.js +2 -3
- package/lib/core/codec-pool.js +1 -1
- package/lib/core/configuration.js +29 -8
- package/lib/core/io.js +36 -46
- package/lib/core/streams/aes-crypto-stream.js +86 -61
- package/lib/core/streams/codec-stream.js +2 -6
- package/lib/core/streams/common-crypto.js +3 -1
- package/lib/core/streams/zip-crypto-stream.js +12 -15
- package/lib/core/streams/zip-entry-stream.js +41 -57
- package/lib/core/z-worker-core.js +9 -9
- package/lib/core/zip-reader.js +50 -34
- package/lib/core/zip-writer.js +87 -67
- package/lib/z-worker-inline.js +1 -1
- package/package.json +5 -2
- package/rollup-fflate.config.dev.js +5 -2
- package/rollup-fflate.config.js +5 -2
- package/rollup.config.dev.js +5 -2
- package/rollup.config.js +5 -2
- package/tests/all/test-common-js.cjs +31 -0
- package/tests/tests-data.js +1 -0
- package/tests/web-runner.js +4 -1
|
@@ -39,7 +39,6 @@ const HEADER_LENGTH = 12;
|
|
|
39
39
|
class ZipCryptoDecryptionStream extends TransformStream {
|
|
40
40
|
|
|
41
41
|
constructor(password, passwordVerification) {
|
|
42
|
-
let stream;
|
|
43
42
|
super({
|
|
44
43
|
start() {
|
|
45
44
|
Object.assign(this, {
|
|
@@ -59,12 +58,8 @@ class ZipCryptoDecryptionStream extends TransformStream {
|
|
|
59
58
|
chunk = chunk.subarray(HEADER_LENGTH);
|
|
60
59
|
}
|
|
61
60
|
controller.enqueue(decrypt(zipCrypto, chunk));
|
|
62
|
-
},
|
|
63
|
-
flush() {
|
|
64
|
-
stream.valid = true;
|
|
65
61
|
}
|
|
66
62
|
});
|
|
67
|
-
stream = this;
|
|
68
63
|
}
|
|
69
64
|
}
|
|
70
65
|
|
|
@@ -96,8 +91,6 @@ class ZipCryptoEncryptionStream extends TransformStream {
|
|
|
96
91
|
}
|
|
97
92
|
output.set(encrypt(zipCrypto, chunk), offset);
|
|
98
93
|
controller.enqueue(output);
|
|
99
|
-
},
|
|
100
|
-
flush() {
|
|
101
94
|
}
|
|
102
95
|
});
|
|
103
96
|
}
|
|
@@ -128,21 +121,25 @@ function encrypt(target, input) {
|
|
|
128
121
|
}
|
|
129
122
|
|
|
130
123
|
function createKeys(target, password) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
const keys = [0x12345678, 0x23456789, 0x34567890];
|
|
125
|
+
Object.assign(target, {
|
|
126
|
+
keys,
|
|
127
|
+
crcKey0: new Crc32(keys[0]),
|
|
128
|
+
crcKey2: new Crc32(keys[2]),
|
|
129
|
+
});
|
|
134
130
|
for (let index = 0; index < password.length; index++) {
|
|
135
131
|
updateKeys(target, password.charCodeAt(index));
|
|
136
132
|
}
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
function updateKeys(target, byte) {
|
|
136
|
+
let [key0, key1, key2] = target.keys;
|
|
140
137
|
target.crcKey0.append([byte]);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
target.
|
|
144
|
-
target.crcKey2.
|
|
145
|
-
target.keys
|
|
138
|
+
key0 = ~target.crcKey0.get();
|
|
139
|
+
key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1);
|
|
140
|
+
target.crcKey2.append([key1 >>> 24]);
|
|
141
|
+
key2 = ~target.crcKey2.get();
|
|
142
|
+
target.keys = [key0, key1, key2];
|
|
146
143
|
}
|
|
147
144
|
|
|
148
145
|
function getByte(target) {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global
|
|
29
|
+
/* global TransformStream */
|
|
30
30
|
|
|
31
31
|
import { Crc32Stream } from "./crc32-stream.js";
|
|
32
32
|
import {
|
|
@@ -35,51 +35,36 @@ import {
|
|
|
35
35
|
} from "./aes-crypto-stream.js";
|
|
36
36
|
import {
|
|
37
37
|
ZipCryptoEncryptionStream,
|
|
38
|
-
ZipCryptoDecryptionStream
|
|
38
|
+
ZipCryptoDecryptionStream
|
|
39
39
|
} from "./zip-crypto-stream.js";
|
|
40
40
|
import {
|
|
41
|
-
ERR_INVALID_PASSWORD
|
|
41
|
+
ERR_INVALID_PASSWORD,
|
|
42
|
+
ERR_INVALID_SIGNATURE
|
|
42
43
|
} from "./common-crypto.js";
|
|
43
|
-
import { CodecStream } from "./codec-stream.js";
|
|
44
44
|
|
|
45
|
-
const ERR_INVALID_SIGNATURE = "Invalid signature";
|
|
46
45
|
const COMPRESSION_FORMAT = "deflate-raw";
|
|
47
|
-
const UNDEFINED_TYPE = "undefined";
|
|
48
|
-
const COMPRESSION_STREAM_API_SUPPORTED = typeof CompressionStream == UNDEFINED_TYPE;
|
|
49
|
-
const DECOMPRESSION_STREAM_API_SUPPORTED = typeof DecompressionStream == UNDEFINED_TYPE;
|
|
50
|
-
let INFLATE_RAW_SUPPORTED = true;
|
|
51
|
-
let DEFLATE_RAW_SUPPORTED = true;
|
|
52
46
|
|
|
53
47
|
class DeflateStream extends TransformStream {
|
|
54
48
|
|
|
55
|
-
constructor(
|
|
56
|
-
super({}
|
|
49
|
+
constructor(options, { chunkSize, CompressionStream, CompressionStreamNative }) {
|
|
50
|
+
super({});
|
|
57
51
|
const { compressed, encrypted, useCompressionStream, password, passwordVerification, encryptionStrength, zipCrypto, signed, level } = options;
|
|
58
52
|
const stream = this;
|
|
59
53
|
let crc32Stream, encryptionStream;
|
|
60
54
|
let readable = filterEmptyChunks(super.readable);
|
|
61
55
|
if ((!encrypted || zipCrypto) && signed) {
|
|
62
56
|
[readable, crc32Stream] = readable.tee();
|
|
63
|
-
crc32Stream =
|
|
57
|
+
crc32Stream = pipeThrough(crc32Stream, new Crc32Stream());
|
|
64
58
|
}
|
|
65
59
|
if (compressed) {
|
|
66
|
-
|
|
67
|
-
readable = pipeCodecStream(codecConstructor, readable, { chunkSize, level });
|
|
68
|
-
} else {
|
|
69
|
-
try {
|
|
70
|
-
readable = readable.pipeThrough(new CompressionStream(COMPRESSION_FORMAT));
|
|
71
|
-
} catch (_error) {
|
|
72
|
-
DEFLATE_RAW_SUPPORTED = false;
|
|
73
|
-
readable = pipeCodecStream(codecConstructor, readable, { chunkSize, level });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
60
|
+
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStreamNative, CompressionStream);
|
|
76
61
|
}
|
|
77
62
|
if (encrypted) {
|
|
78
63
|
if (zipCrypto) {
|
|
79
|
-
readable =
|
|
64
|
+
readable = pipeThrough(readable, new ZipCryptoEncryptionStream(password, passwordVerification));
|
|
80
65
|
} else {
|
|
81
66
|
encryptionStream = new AESEncryptionStream(password, encryptionStrength);
|
|
82
|
-
readable =
|
|
67
|
+
readable = pipeThrough(readable, encryptionStream);
|
|
83
68
|
}
|
|
84
69
|
}
|
|
85
70
|
setReadable(stream, readable, async () => {
|
|
@@ -98,46 +83,31 @@ class DeflateStream extends TransformStream {
|
|
|
98
83
|
|
|
99
84
|
class InflateStream extends TransformStream {
|
|
100
85
|
|
|
101
|
-
constructor(
|
|
102
|
-
super({}
|
|
103
|
-
const { zipCrypto, encrypted, password, passwordVerification, signed, encryptionStrength, compressed, useCompressionStream } = options;
|
|
104
|
-
const stream = this;
|
|
86
|
+
constructor(options, { chunkSize, DecompressionStream, DecompressionStreamNative }) {
|
|
87
|
+
super({});
|
|
88
|
+
const { zipCrypto, encrypted, password, passwordVerification, signed, signature, encryptionStrength, compressed, useCompressionStream } = options;
|
|
105
89
|
let crc32Stream, decryptionStream;
|
|
106
90
|
let readable = filterEmptyChunks(super.readable);
|
|
107
91
|
if (encrypted) {
|
|
108
92
|
if (zipCrypto) {
|
|
109
|
-
readable =
|
|
93
|
+
readable = pipeThrough(readable, new ZipCryptoDecryptionStream(password, passwordVerification));
|
|
110
94
|
} else {
|
|
111
95
|
decryptionStream = new AESDecryptionStream(password, signed, encryptionStrength);
|
|
112
|
-
readable =
|
|
96
|
+
readable = pipeThrough(readable, decryptionStream);
|
|
113
97
|
}
|
|
114
98
|
}
|
|
115
99
|
if (compressed) {
|
|
116
|
-
|
|
117
|
-
readable = pipeCodecStream(codecConstructor, readable, { chunkSize });
|
|
118
|
-
} else {
|
|
119
|
-
try {
|
|
120
|
-
readable = readable.pipeThrough(new DecompressionStream(COMPRESSION_FORMAT));
|
|
121
|
-
} catch (_error) {
|
|
122
|
-
INFLATE_RAW_SUPPORTED = false;
|
|
123
|
-
readable = pipeCodecStream(codecConstructor, readable, { chunkSize });
|
|
124
|
-
}
|
|
125
|
-
}
|
|
100
|
+
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize }, DecompressionStreamNative, DecompressionStream);
|
|
126
101
|
}
|
|
127
102
|
if ((!encrypted || zipCrypto) && signed) {
|
|
128
103
|
[readable, crc32Stream] = readable.tee();
|
|
129
|
-
crc32Stream =
|
|
104
|
+
crc32Stream = pipeThrough(crc32Stream, new Crc32Stream());
|
|
130
105
|
}
|
|
131
|
-
setReadable(
|
|
132
|
-
if (encrypted && !zipCrypto) {
|
|
133
|
-
if (!decryptionStream.valid) {
|
|
134
|
-
throw new Error(ERR_INVALID_SIGNATURE);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
106
|
+
setReadable(this, readable, async () => {
|
|
137
107
|
if ((!encrypted || zipCrypto) && signed) {
|
|
138
|
-
const
|
|
139
|
-
const dataViewSignature = new DataView(
|
|
140
|
-
if (
|
|
108
|
+
const streamSignature = await crc32Stream.getReader().read();
|
|
109
|
+
const dataViewSignature = new DataView(streamSignature.value.buffer);
|
|
110
|
+
if (signature != dataViewSignature.getUint32(0, false)) {
|
|
141
111
|
throw new Error(ERR_INVALID_SIGNATURE);
|
|
142
112
|
}
|
|
143
113
|
}
|
|
@@ -152,12 +122,8 @@ export {
|
|
|
152
122
|
ERR_INVALID_SIGNATURE
|
|
153
123
|
};
|
|
154
124
|
|
|
155
|
-
function pipeCodecStream(codecConstructor, readable, options) {
|
|
156
|
-
return readable.pipeThrough(new CodecStream(codecConstructor, options));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
125
|
function filterEmptyChunks(readable) {
|
|
160
|
-
return
|
|
126
|
+
return pipeThrough(readable, new TransformStream({
|
|
161
127
|
transform(chunk, controller) {
|
|
162
128
|
if (chunk && chunk.length) {
|
|
163
129
|
controller.enqueue(chunk);
|
|
@@ -167,10 +133,28 @@ function filterEmptyChunks(readable) {
|
|
|
167
133
|
}
|
|
168
134
|
|
|
169
135
|
function setReadable(stream, readable, flush) {
|
|
170
|
-
readable =
|
|
136
|
+
readable = pipeThrough(readable, new TransformStream({ flush }));
|
|
171
137
|
Object.defineProperty(stream, "readable", {
|
|
172
138
|
get() {
|
|
173
139
|
return readable;
|
|
174
140
|
}
|
|
175
141
|
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function pipeThroughCommpressionStream(readable, useCompressionStream, options, CodecStreamNative, CodecStream) {
|
|
145
|
+
try {
|
|
146
|
+
const CompressionStream = useCompressionStream && CodecStreamNative ? CodecStreamNative : CodecStream;
|
|
147
|
+
readable = pipeThrough(readable, new CompressionStream(COMPRESSION_FORMAT, options));
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (useCompressionStream) {
|
|
150
|
+
readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options));
|
|
151
|
+
} else {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return readable;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function pipeThrough(readable, transformStream) {
|
|
159
|
+
return readable.pipeThrough(transformStream);
|
|
176
160
|
}
|
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
Codec,
|
|
33
|
-
|
|
34
|
-
CODEC_INFLATE,
|
|
33
|
+
getCodecStreamClass,
|
|
35
34
|
MESSAGE_EVENT_TYPE,
|
|
36
35
|
MESSAGE_START,
|
|
37
36
|
MESSAGE_PULL,
|
|
@@ -70,18 +69,19 @@ addEventListener(MESSAGE_EVENT_TYPE, async event => {
|
|
|
70
69
|
async function init(message) {
|
|
71
70
|
try {
|
|
72
71
|
const { options, scripts, config } = message;
|
|
73
|
-
const { codecType } = options;
|
|
74
72
|
if (scripts && scripts.length) {
|
|
75
73
|
importScripts.apply(undefined, scripts);
|
|
76
74
|
}
|
|
77
75
|
if (self.initCodec) {
|
|
78
76
|
self.initCodec();
|
|
79
77
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
config.CompressionStreamNative = self.CompressionStream;
|
|
79
|
+
config.DecompressionStreamNative = self.DecompressionStream;
|
|
80
|
+
if (self.Deflate) {
|
|
81
|
+
config.CompressionStream = getCodecStreamClass(self.Deflate);
|
|
82
|
+
}
|
|
83
|
+
if (self.Inflate) {
|
|
84
|
+
config.DecompressionStream = getCodecStreamClass(self.Inflate);
|
|
85
85
|
}
|
|
86
86
|
const strategy = { highWaterMark: 1, size: () => config.chunkSize };
|
|
87
87
|
const readable = message.readable || new ReadableStream({
|
|
@@ -106,7 +106,7 @@ async function init(message) {
|
|
|
106
106
|
await ackData;
|
|
107
107
|
}
|
|
108
108
|
}, strategy);
|
|
109
|
-
codec = new Codec(
|
|
109
|
+
codec = new Codec(readable, writable, options, config);
|
|
110
110
|
const result = await codec.run();
|
|
111
111
|
if (message.writable && !options.preventClose) {
|
|
112
112
|
await message.writable.close();
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -186,40 +186,48 @@ class ZipReader {
|
|
|
186
186
|
const commentOffset = extraFieldOffset + fileEntry.extraFieldLength;
|
|
187
187
|
const versionMadeBy = getUint16(directoryView, offset + 4);
|
|
188
188
|
const msDosCompatible = (versionMadeBy & 0) == 0;
|
|
189
|
+
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
190
|
+
const commentLength = getUint16(directoryView, offset + 32);
|
|
191
|
+
const endOffset = commentOffset + commentLength;
|
|
192
|
+
const rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
193
|
+
const filenameUTF8 = languageEncodingFlag;
|
|
194
|
+
const commentUTF8 = languageEncodingFlag;
|
|
195
|
+
const directory = msDosCompatible && ((getUint8(directoryView, offset + 38) & FILE_ATTR_MSDOS_DIR_MASK) == FILE_ATTR_MSDOS_DIR_MASK);
|
|
196
|
+
const offsetFileEntry = getUint32(directoryView, offset + 42) + prependedDataLength;
|
|
189
197
|
Object.assign(fileEntry, {
|
|
190
198
|
versionMadeBy,
|
|
191
199
|
msDosCompatible,
|
|
192
200
|
compressedSize: 0,
|
|
193
201
|
uncompressedSize: 0,
|
|
194
|
-
commentLength
|
|
195
|
-
directory
|
|
196
|
-
offset:
|
|
202
|
+
commentLength,
|
|
203
|
+
directory,
|
|
204
|
+
offset: offsetFileEntry,
|
|
197
205
|
internalFileAttribute: getUint16(directoryView, offset + 36),
|
|
198
206
|
externalFileAttribute: getUint32(directoryView, offset + 38),
|
|
199
|
-
rawFilename
|
|
200
|
-
filenameUTF8
|
|
201
|
-
commentUTF8
|
|
207
|
+
rawFilename,
|
|
208
|
+
filenameUTF8,
|
|
209
|
+
commentUTF8,
|
|
202
210
|
rawExtraField: directoryArray.subarray(extraFieldOffset, commentOffset)
|
|
203
211
|
});
|
|
204
|
-
startOffset = Math.max(fileEntry.offset, startOffset);
|
|
205
|
-
const endOffset = commentOffset + fileEntry.commentLength;
|
|
206
|
-
fileEntry.rawComment = directoryArray.subarray(commentOffset, endOffset);
|
|
207
212
|
const [filename, comment] = await Promise.all([
|
|
208
|
-
decodeText(
|
|
209
|
-
decodeText(
|
|
213
|
+
decodeText(rawFilename, filenameUTF8 ? CHARSET_UTF8 : filenameEncoding || CHARSET_CP437),
|
|
214
|
+
decodeText(rawComment, commentUTF8 ? CHARSET_UTF8 : commentEncoding || CHARSET_CP437)
|
|
210
215
|
]);
|
|
211
|
-
fileEntry
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
+
Object.assign(fileEntry, {
|
|
217
|
+
rawComment,
|
|
218
|
+
filename,
|
|
219
|
+
comment,
|
|
220
|
+
directory: directory || filename.endsWith(DIRECTORY_SIGNATURE)
|
|
221
|
+
});
|
|
222
|
+
startOffset = Math.max(offsetFileEntry, startOffset);
|
|
216
223
|
await readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
|
|
217
224
|
const entry = new Entry(fileEntry);
|
|
218
225
|
entry.getData = (writer, options) => fileEntry.getData(writer, entry, options);
|
|
219
226
|
offset = endOffset;
|
|
220
|
-
|
|
227
|
+
const { onprogress } = options;
|
|
228
|
+
if (onprogress) {
|
|
221
229
|
try {
|
|
222
|
-
await
|
|
230
|
+
await onprogress(indexFile + 1, filesLength, new Entry(fileEntry));
|
|
223
231
|
} catch (_error) {
|
|
224
232
|
// ignored
|
|
225
233
|
}
|
|
@@ -310,8 +318,10 @@ class ZipEntry {
|
|
|
310
318
|
dataArray = await readUint8Array(reader, offset, 30 + localDirectory.filenameLength + localDirectory.extraFieldLength);
|
|
311
319
|
localDirectory.rawExtraField = dataArray.subarray(30 + localDirectory.filenameLength);
|
|
312
320
|
await readCommonFooter(zipEntry, localDirectory, dataView, 4);
|
|
313
|
-
fileEntry
|
|
314
|
-
|
|
321
|
+
Object.assign(fileEntry, {
|
|
322
|
+
lastAccessDate: localDirectory.lastAccessDate,
|
|
323
|
+
creationDate: localDirectory.creationDate
|
|
324
|
+
});
|
|
315
325
|
const encrypted = zipEntry.encrypted && localDirectory.encrypted;
|
|
316
326
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
317
327
|
if (encrypted) {
|
|
@@ -355,8 +365,7 @@ class ZipEntry {
|
|
|
355
365
|
preventClose
|
|
356
366
|
},
|
|
357
367
|
config,
|
|
358
|
-
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
359
|
-
codecConstructor: config.Inflate
|
|
368
|
+
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
360
369
|
};
|
|
361
370
|
writable.size += (await runWorker({ readable, writable }, workerOptions)).size;
|
|
362
371
|
if (!preventClose) {
|
|
@@ -408,9 +417,11 @@ async function readCommonFooter(fileEntry, directory, dataView, offset) {
|
|
|
408
417
|
// ignored
|
|
409
418
|
}
|
|
410
419
|
const compressionMethod = getUint16(dataView, offset + 4);
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
420
|
+
Object.assign(directory, {
|
|
421
|
+
signature: getUint32(dataView, offset + 10),
|
|
422
|
+
uncompressedSize: getUint32(dataView, offset + 18),
|
|
423
|
+
compressedSize: getUint32(dataView, offset + 14)
|
|
424
|
+
});
|
|
414
425
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
415
426
|
if (extraFieldZip64) {
|
|
416
427
|
readExtraFieldZip64(extraFieldZip64, directory);
|
|
@@ -469,14 +480,16 @@ function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
|
469
480
|
|
|
470
481
|
async function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
|
|
471
482
|
const extraFieldView = getDataView(extraFieldUnicode.data);
|
|
472
|
-
extraFieldUnicode.version = getUint8(extraFieldView, 0);
|
|
473
|
-
extraFieldUnicode.signature = getUint32(extraFieldView, 1);
|
|
474
483
|
const crc32 = new Crc32();
|
|
475
484
|
crc32.append(fileEntry[rawPropertyName]);
|
|
476
485
|
const dataViewSignature = getDataView(new Uint8Array(4));
|
|
477
486
|
dataViewSignature.setUint32(0, crc32.get(), true);
|
|
478
|
-
extraFieldUnicode
|
|
479
|
-
|
|
487
|
+
Object.assign(extraFieldUnicode, {
|
|
488
|
+
version: getUint8(extraFieldView, 0),
|
|
489
|
+
signature: getUint32(extraFieldView, 1),
|
|
490
|
+
[propertyName]: await decodeText(extraFieldUnicode.data.subarray(5)),
|
|
491
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && extraFieldUnicode.signature == getUint32(dataViewSignature, 0)
|
|
492
|
+
});
|
|
480
493
|
if (extraFieldUnicode.valid) {
|
|
481
494
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
482
495
|
directory[propertyName + "UTF8"] = true;
|
|
@@ -485,12 +498,15 @@ async function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropert
|
|
|
485
498
|
|
|
486
499
|
function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
|
|
487
500
|
const extraFieldView = getDataView(extraFieldAES.data);
|
|
488
|
-
extraFieldAES.vendorVersion = getUint8(extraFieldView, 0);
|
|
489
|
-
extraFieldAES.vendorId = getUint8(extraFieldView, 2);
|
|
490
501
|
const strength = getUint8(extraFieldView, 4);
|
|
491
|
-
extraFieldAES
|
|
492
|
-
|
|
493
|
-
|
|
502
|
+
Object.assign(extraFieldAES, {
|
|
503
|
+
vendorVersion: getUint8(extraFieldView, 0),
|
|
504
|
+
vendorId: getUint8(extraFieldView, 2),
|
|
505
|
+
strength,
|
|
506
|
+
originalCompressionMethod: compressionMethod,
|
|
507
|
+
compressionMethod: getUint16(extraFieldView, 5)
|
|
508
|
+
});
|
|
509
|
+
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
494
510
|
}
|
|
495
511
|
|
|
496
512
|
function readExtraFieldNTFS(extraFieldNTFS, directory) {
|