@zip.js/zip.js 2.6.29 → 2.6.31
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 +150 -48
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +151 -48
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +151 -48
- 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 +151 -48
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +3 -1
- package/index.cjs +149 -47
- package/index.d.ts +8 -2
- package/index.js +3 -1
- package/lib/core/codec-pool-worker.js +27 -4
- package/lib/core/io.js +54 -2
- package/lib/core/z-worker-core.js +4 -2
- package/lib/core/zip-reader.js +73 -43
- package/lib/z-worker-inline.js +1 -1
- package/package.json +1 -1
- package/rollup-fflate.config.dev.js +2 -2
- package/rollup-fflate.config.js +2 -2
- package/rollup.config.dev.js +2 -2
- package/rollup.config.js +3 -3
- package/tests/all/test-split-zip.js +37 -0
- package/tests/data/lorem-split.z01 +0 -0
- package/tests/data/lorem-split.z02 +0 -0
- package/tests/data/lorem-split.z03 +0 -0
- package/tests/data/lorem-split.z04 +0 -0
- package/tests/data/lorem-split.z05 +0 -0
- package/tests/data/lorem-split.z06 +0 -0
- package/tests/data/lorem-split.z07 +0 -0
- package/tests/data/lorem-split.zip +0 -0
- package/tests/tests-data.js +1 -0
package/index.js
CHANGED
|
@@ -54,6 +54,7 @@ export {
|
|
|
54
54
|
HttpRangeReader,
|
|
55
55
|
Uint8ArrayWriter,
|
|
56
56
|
Uint8ArrayReader,
|
|
57
|
+
SplitZipReader,
|
|
57
58
|
ERR_HTTP_RANGE,
|
|
58
59
|
ERR_BAD_FORMAT,
|
|
59
60
|
ERR_EOCDR_NOT_FOUND,
|
|
@@ -75,6 +76,7 @@ export {
|
|
|
75
76
|
ERR_INVALID_EXTRAFIELD_TYPE,
|
|
76
77
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
77
78
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
78
|
-
ERR_UNSUPPORTED_FORMAT
|
|
79
|
+
ERR_UNSUPPORTED_FORMAT,
|
|
80
|
+
ERR_SPLIT_ZIP_FILE
|
|
79
81
|
} from "./lib/zip-fs.js";
|
|
80
82
|
export { getMimeType, terminateWorkers };
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Worker, URL, TransformStream */
|
|
29
|
+
/* global Worker, URL, TransformStream, WritableStream */
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
Codec,
|
|
@@ -141,8 +141,24 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
141
141
|
}
|
|
142
142
|
workerData.worker.addEventListener(MESSAGE_EVENT_TYPE, onMessage, false);
|
|
143
143
|
workerData.interface = {
|
|
144
|
-
run() {
|
|
145
|
-
const { readable,
|
|
144
|
+
async run() {
|
|
145
|
+
const { readable, options } = workerData;
|
|
146
|
+
const writer = workerData.writable.getWriter();
|
|
147
|
+
let resolveStreamClosed, streamClosed;
|
|
148
|
+
streamClosed = new Promise(resolve => resolveStreamClosed = resolve);
|
|
149
|
+
const writable = new WritableStream({
|
|
150
|
+
async write(chunk) {
|
|
151
|
+
await writer.ready;
|
|
152
|
+
await writer.write(new Uint8Array(chunk));
|
|
153
|
+
},
|
|
154
|
+
async close() {
|
|
155
|
+
writer.releaseLock();
|
|
156
|
+
resolveStreamClosed();
|
|
157
|
+
},
|
|
158
|
+
abort(reason) {
|
|
159
|
+
writer.abort(reason);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
146
162
|
const scripts = workerData.scripts.slice(1);
|
|
147
163
|
const message = { type: MESSAGE_START, scripts, options, config: { chunkSize } };
|
|
148
164
|
if (workerData.transferStreams && transferStreamsSupported) {
|
|
@@ -155,7 +171,14 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
155
171
|
sendMessage(message);
|
|
156
172
|
initStreams(readable, writable);
|
|
157
173
|
}
|
|
158
|
-
|
|
174
|
+
const result = await workerData.result;
|
|
175
|
+
try {
|
|
176
|
+
await writable.close();
|
|
177
|
+
} catch (_error) {
|
|
178
|
+
// ignored
|
|
179
|
+
}
|
|
180
|
+
await streamClosed;
|
|
181
|
+
return result;
|
|
159
182
|
}
|
|
160
183
|
};
|
|
161
184
|
}
|
package/lib/core/io.js
CHANGED
|
@@ -64,9 +64,9 @@ class Reader extends Stream {
|
|
|
64
64
|
this.chunkOffset = 0;
|
|
65
65
|
},
|
|
66
66
|
async pull(controller) {
|
|
67
|
-
const { offset = 0, size } = readable;
|
|
67
|
+
const { offset = 0, size, diskNumberStart } = readable;
|
|
68
68
|
const { chunkOffset } = this;
|
|
69
|
-
controller.enqueue(await
|
|
69
|
+
controller.enqueue(await readUint8Array(reader, offset + chunkOffset, Math.min(chunkSize, size - chunkOffset), diskNumberStart));
|
|
70
70
|
if (chunkOffset + chunkSize > size) {
|
|
71
71
|
controller.close();
|
|
72
72
|
} else {
|
|
@@ -483,6 +483,52 @@ class Uint8ArrayWriter extends Writer {
|
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
485
|
|
|
486
|
+
class SplitZipReader extends Reader {
|
|
487
|
+
|
|
488
|
+
constructor(readers) {
|
|
489
|
+
super();
|
|
490
|
+
this.readers = readers;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async init() {
|
|
494
|
+
super.init();
|
|
495
|
+
const reader = this;
|
|
496
|
+
const { readers } = reader;
|
|
497
|
+
reader.lastDiskNumber = 0;
|
|
498
|
+
await Promise.all(readers.map(async diskReader => {
|
|
499
|
+
await diskReader.init();
|
|
500
|
+
reader.size += diskReader.size;
|
|
501
|
+
}));
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
async readUint8Array(offset, length, diskNumber = 0) {
|
|
505
|
+
const reader = this;
|
|
506
|
+
const { readers } = this;
|
|
507
|
+
let result;
|
|
508
|
+
let currentDiskNumber = diskNumber;
|
|
509
|
+
if (currentDiskNumber == -1) {
|
|
510
|
+
currentDiskNumber = readers.length - 1;
|
|
511
|
+
}
|
|
512
|
+
let currentReaderOffset = offset;
|
|
513
|
+
while (currentReaderOffset >= readers[currentDiskNumber].size) {
|
|
514
|
+
currentReaderOffset -= readers[currentDiskNumber].size;
|
|
515
|
+
currentDiskNumber++;
|
|
516
|
+
}
|
|
517
|
+
const currentReader = readers[currentDiskNumber];
|
|
518
|
+
const currentReaderSize = currentReader.size;
|
|
519
|
+
if (currentReaderOffset + length <= currentReaderSize) {
|
|
520
|
+
result = await readUint8Array(currentReader, currentReaderOffset, length);
|
|
521
|
+
} else {
|
|
522
|
+
const chunkLength = currentReaderSize - currentReaderOffset;
|
|
523
|
+
result = new Uint8Array(length);
|
|
524
|
+
result.set(await readUint8Array(currentReader, currentReaderOffset, chunkLength));
|
|
525
|
+
result.set(await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber), chunkLength);
|
|
526
|
+
}
|
|
527
|
+
reader.lastDiskNumber = Math.max(currentDiskNumber, reader.lastDiskNumber);
|
|
528
|
+
return result;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
486
532
|
function isHttpFamily(url) {
|
|
487
533
|
const { baseURL } = getConfiguration();
|
|
488
534
|
const { protocol } = new URL(url, baseURL);
|
|
@@ -495,8 +541,13 @@ async function initStream(stream, initSize) {
|
|
|
495
541
|
}
|
|
496
542
|
}
|
|
497
543
|
|
|
544
|
+
function readUint8Array(reader, offset, size, diskNumber) {
|
|
545
|
+
return reader.readUint8Array(offset, size, diskNumber);
|
|
546
|
+
}
|
|
547
|
+
|
|
498
548
|
export {
|
|
499
549
|
initStream,
|
|
550
|
+
readUint8Array,
|
|
500
551
|
Reader,
|
|
501
552
|
Writer,
|
|
502
553
|
TextReader,
|
|
@@ -509,5 +560,6 @@ export {
|
|
|
509
560
|
Uint8ArrayWriter,
|
|
510
561
|
HttpReader,
|
|
511
562
|
HttpRangeReader,
|
|
563
|
+
SplitZipReader,
|
|
512
564
|
ERR_HTTP_RANGE
|
|
513
565
|
};
|
|
@@ -108,8 +108,10 @@ async function init(message) {
|
|
|
108
108
|
}, strategy);
|
|
109
109
|
codec = new Codec(readable, writable, options, config);
|
|
110
110
|
const result = await codec.run();
|
|
111
|
-
|
|
112
|
-
await
|
|
111
|
+
try {
|
|
112
|
+
await writable.close();
|
|
113
|
+
} catch (_error) {
|
|
114
|
+
// ignored
|
|
113
115
|
}
|
|
114
116
|
sendMessage({ type: MESSAGE_CLOSE, result });
|
|
115
117
|
} catch (error) {
|
package/lib/core/zip-reader.js
CHANGED
|
@@ -68,12 +68,15 @@ import {
|
|
|
68
68
|
} from "./codec-pool.js";
|
|
69
69
|
import {
|
|
70
70
|
initStream,
|
|
71
|
-
|
|
71
|
+
readUint8Array,
|
|
72
|
+
BlobReader,
|
|
73
|
+
SplitZipReader
|
|
72
74
|
} from "./io.js";
|
|
73
75
|
import { decodeText } from "./util/decode-text.js";
|
|
74
76
|
import { Crc32 } from "./streams/codecs/crc32.js";
|
|
75
77
|
import { Entry } from "./zip-entry.js";
|
|
76
78
|
|
|
79
|
+
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
77
80
|
const ERR_BAD_FORMAT = "File format is not recognized";
|
|
78
81
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
79
82
|
const ERR_EOCDR_ZIP64_NOT_FOUND = "End of Zip64 central directory not found";
|
|
@@ -84,9 +87,25 @@ const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
|
84
87
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
85
88
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
86
89
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
90
|
+
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
87
91
|
const CHARSET_UTF8 = "utf-8";
|
|
88
92
|
const CHARSET_CP437 = "cp437";
|
|
89
|
-
const ZIP64_PROPERTIES = [
|
|
93
|
+
const ZIP64_PROPERTIES = [
|
|
94
|
+
["uncompressedSize", MAX_32_BITS],
|
|
95
|
+
["compressedSize", MAX_32_BITS],
|
|
96
|
+
["offset", MAX_32_BITS],
|
|
97
|
+
["diskNumberStart", MAX_16_BITS]
|
|
98
|
+
];
|
|
99
|
+
const ZIP64_EXTRACTION = {
|
|
100
|
+
[MAX_16_BITS]: {
|
|
101
|
+
getValue: getUint32,
|
|
102
|
+
bytes: 4
|
|
103
|
+
},
|
|
104
|
+
[MAX_32_BITS]: {
|
|
105
|
+
getValue: getBigUint64,
|
|
106
|
+
bytes: 8
|
|
107
|
+
}
|
|
108
|
+
};
|
|
90
109
|
|
|
91
110
|
class ZipReader {
|
|
92
111
|
|
|
@@ -109,8 +128,12 @@ class ZipReader {
|
|
|
109
128
|
const { config } = zipReader;
|
|
110
129
|
await initStream(reader);
|
|
111
130
|
if (reader.size === undefined || !reader.readUint8Array) {
|
|
112
|
-
|
|
113
|
-
|
|
131
|
+
if (Array.isArray(reader)) {
|
|
132
|
+
reader = new SplitZipReader(reader);
|
|
133
|
+
} else {
|
|
134
|
+
reader = new BlobReader(await new Response(reader.readable).blob());
|
|
135
|
+
}
|
|
136
|
+
await initStream(reader);
|
|
114
137
|
}
|
|
115
138
|
if (reader.size < END_OF_CENTRAL_DIR_LENGTH) {
|
|
116
139
|
throw new Error(ERR_BAD_FORMAT);
|
|
@@ -118,46 +141,64 @@ class ZipReader {
|
|
|
118
141
|
reader.chunkSize = getChunkSize(config);
|
|
119
142
|
const endOfDirectoryInfo = await seekSignature(reader, END_OF_CENTRAL_DIR_SIGNATURE, reader.size, END_OF_CENTRAL_DIR_LENGTH, MAX_16_BITS * 16);
|
|
120
143
|
if (!endOfDirectoryInfo) {
|
|
121
|
-
|
|
144
|
+
const signatureArray = await readUint8Array(reader, 0, 4);
|
|
145
|
+
const signatureView = getDataView(signatureArray);
|
|
146
|
+
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
147
|
+
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
148
|
+
} else {
|
|
149
|
+
throw new Error(ERR_EOCDR_NOT_FOUND);
|
|
150
|
+
}
|
|
122
151
|
}
|
|
152
|
+
const { lastDiskNumber } = reader;
|
|
123
153
|
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
124
154
|
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
125
155
|
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
126
156
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
127
157
|
const commentLength = getUint16(endOfDirectoryView, 20);
|
|
128
158
|
const appendedDataOffset = commentOffset + END_OF_CENTRAL_DIR_LENGTH + commentLength;
|
|
159
|
+
let diskNumber = getUint16(endOfDirectoryView, 4);
|
|
160
|
+
if (lastDiskNumber !== undefined && diskNumber != lastDiskNumber) {
|
|
161
|
+
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
162
|
+
}
|
|
129
163
|
let filesLength = getUint16(endOfDirectoryView, 8);
|
|
130
164
|
let prependedDataLength = 0;
|
|
131
165
|
let startOffset = 0;
|
|
132
|
-
if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS) {
|
|
166
|
+
if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
|
|
133
167
|
const endOfDirectoryLocatorArray = await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH);
|
|
134
168
|
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
135
169
|
if (getUint32(endOfDirectoryLocatorView, 0) != ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
136
170
|
throw new Error(ERR_EOCDR_ZIP64_NOT_FOUND);
|
|
137
171
|
}
|
|
138
172
|
directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
|
|
139
|
-
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
173
|
+
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
|
|
140
174
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
141
175
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
142
176
|
if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE && directoryDataOffset != expectedDirectoryDataOffset) {
|
|
143
177
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
144
178
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
145
179
|
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
146
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
180
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
|
|
147
181
|
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
148
182
|
}
|
|
149
183
|
if (getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
150
184
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
151
185
|
}
|
|
152
|
-
|
|
153
|
-
|
|
186
|
+
if (diskNumber == MAX_16_BITS) {
|
|
187
|
+
diskNumber = getUint32(endOfDirectoryView, 16);
|
|
188
|
+
}
|
|
189
|
+
if (filesLength == MAX_16_BITS) {
|
|
190
|
+
filesLength = getBigUint64(endOfDirectoryView, 32);
|
|
191
|
+
}
|
|
192
|
+
if (directoryDataLength == MAX_32_BITS) {
|
|
193
|
+
directoryDataLength = getBigUint64(endOfDirectoryView, 40);
|
|
194
|
+
}
|
|
154
195
|
directoryDataOffset -= directoryDataLength;
|
|
155
196
|
}
|
|
156
197
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
157
198
|
throw new Error(ERR_BAD_FORMAT);
|
|
158
199
|
}
|
|
159
200
|
let offset = 0;
|
|
160
|
-
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
201
|
+
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
|
|
161
202
|
let directoryView = getDataView(directoryArray);
|
|
162
203
|
if (directoryDataLength) {
|
|
163
204
|
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - directoryDataLength;
|
|
@@ -165,7 +206,7 @@ class ZipReader {
|
|
|
165
206
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
166
207
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
167
208
|
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
168
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
209
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
|
|
169
210
|
directoryView = getDataView(directoryArray);
|
|
170
211
|
}
|
|
171
212
|
}
|
|
@@ -202,6 +243,7 @@ class ZipReader {
|
|
|
202
243
|
commentLength,
|
|
203
244
|
directory,
|
|
204
245
|
offset: offsetFileEntry,
|
|
246
|
+
diskNumberStart: getUint16(directoryView, offset + 34),
|
|
205
247
|
internalFileAttribute: getUint16(directoryView, offset + 36),
|
|
206
248
|
externalFileAttribute: getUint32(directoryView, offset + 38),
|
|
207
249
|
rawFilename,
|
|
@@ -271,7 +313,8 @@ export {
|
|
|
271
313
|
ERR_UNSUPPORTED_ENCRYPTION,
|
|
272
314
|
ERR_UNSUPPORTED_COMPRESSION,
|
|
273
315
|
ERR_INVALID_SIGNATURE,
|
|
274
|
-
ERR_INVALID_PASSWORD
|
|
316
|
+
ERR_INVALID_PASSWORD,
|
|
317
|
+
ERR_SPLIT_ZIP_FILE
|
|
275
318
|
};
|
|
276
319
|
|
|
277
320
|
class ZipEntry {
|
|
@@ -289,6 +332,7 @@ class ZipEntry {
|
|
|
289
332
|
const {
|
|
290
333
|
reader,
|
|
291
334
|
offset,
|
|
335
|
+
diskNumberStart,
|
|
292
336
|
extraFieldAES,
|
|
293
337
|
compressionMethod,
|
|
294
338
|
config,
|
|
@@ -299,7 +343,7 @@ class ZipEntry {
|
|
|
299
343
|
compressedSize
|
|
300
344
|
} = zipEntry;
|
|
301
345
|
const localDirectory = zipEntry.localDirectory = {};
|
|
302
|
-
let dataArray = await readUint8Array(reader, offset, 30);
|
|
346
|
+
let dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
|
|
303
347
|
const dataView = getDataView(dataArray);
|
|
304
348
|
let password = getOptionValue(zipEntry, options, "password");
|
|
305
349
|
password = password && password.length && password;
|
|
@@ -315,7 +359,7 @@ class ZipEntry {
|
|
|
315
359
|
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
316
360
|
}
|
|
317
361
|
readCommonHeader(localDirectory, dataView, 4);
|
|
318
|
-
dataArray = await readUint8Array(reader, offset, 30 + localDirectory.filenameLength + localDirectory.extraFieldLength);
|
|
362
|
+
dataArray = await readUint8Array(reader, offset, 30 + localDirectory.filenameLength + localDirectory.extraFieldLength, diskNumberStart);
|
|
319
363
|
localDirectory.rawExtraField = dataArray.subarray(30 + localDirectory.filenameLength);
|
|
320
364
|
await readCommonFooter(zipEntry, localDirectory, dataView, 4);
|
|
321
365
|
Object.assign(fileEntry, {
|
|
@@ -333,6 +377,7 @@ class ZipEntry {
|
|
|
333
377
|
}
|
|
334
378
|
const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
|
|
335
379
|
const readable = reader.readable;
|
|
380
|
+
readable.diskNumberStart = diskNumberStart;
|
|
336
381
|
readable.offset = dataOffset;
|
|
337
382
|
const size = readable.size = compressedSize;
|
|
338
383
|
if (writer instanceof WritableStream) {
|
|
@@ -345,7 +390,6 @@ class ZipEntry {
|
|
|
345
390
|
writable.size = 0;
|
|
346
391
|
}
|
|
347
392
|
const signal = getOptionValue(zipEntry, options, "signal");
|
|
348
|
-
const preventClose = getOptionValue(zipEntry, options, "preventClose");
|
|
349
393
|
await initStream(writer, uncompressedSize);
|
|
350
394
|
const { onstart, onprogress, onend } = options;
|
|
351
395
|
const workerOptions = {
|
|
@@ -361,19 +405,15 @@ class ZipEntry {
|
|
|
361
405
|
encrypted,
|
|
362
406
|
useWebWorkers: getOptionValue(zipEntry, options, "useWebWorkers"),
|
|
363
407
|
useCompressionStream: getOptionValue(zipEntry, options, "useCompressionStream"),
|
|
364
|
-
transferStreams: getOptionValue(zipEntry, options, "transferStreams")
|
|
365
|
-
preventClose
|
|
408
|
+
transferStreams: getOptionValue(zipEntry, options, "transferStreams")
|
|
366
409
|
},
|
|
367
410
|
config,
|
|
368
411
|
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
369
412
|
};
|
|
370
413
|
writable.size += (await runWorker({ readable, writable }, workerOptions)).size;
|
|
414
|
+
const preventClose = getOptionValue(zipEntry, options, "preventClose");
|
|
371
415
|
if (!preventClose) {
|
|
372
|
-
|
|
373
|
-
await writable.close();
|
|
374
|
-
} catch (_error) {
|
|
375
|
-
// ignored
|
|
376
|
-
}
|
|
416
|
+
await writable.close();
|
|
377
417
|
}
|
|
378
418
|
return writer.getData ? writer.getData() : writable;
|
|
379
419
|
}
|
|
@@ -459,23 +499,17 @@ async function readCommonFooter(fileEntry, directory, dataView, offset) {
|
|
|
459
499
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
460
500
|
directory.zip64 = true;
|
|
461
501
|
const extraFieldView = getDataView(extraFieldZip64.data);
|
|
462
|
-
|
|
463
|
-
for (let
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (directory[propertyName] == MAX_32_BITS) {
|
|
472
|
-
if (extraFieldZip64[propertyName] !== undefined) {
|
|
473
|
-
directory[propertyName] = extraFieldZip64[propertyName];
|
|
474
|
-
} else {
|
|
475
|
-
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
476
|
-
}
|
|
502
|
+
const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
|
|
503
|
+
for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
|
|
504
|
+
const [propertyName, max] = missingProperties[indexMissingProperty];
|
|
505
|
+
if (directory[propertyName] == max) {
|
|
506
|
+
const extraction = ZIP64_EXTRACTION[max];
|
|
507
|
+
directory[propertyName] = extraFieldZip64[propertyName] = extraction.getValue(extraFieldView, offset);
|
|
508
|
+
offset += extraction.bytes;
|
|
509
|
+
} else if (extraFieldZip64[propertyName]) {
|
|
510
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
477
511
|
}
|
|
478
|
-
}
|
|
512
|
+
}
|
|
479
513
|
}
|
|
480
514
|
|
|
481
515
|
async function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
|
|
@@ -638,8 +672,4 @@ function setUint32(view, offset, value) {
|
|
|
638
672
|
|
|
639
673
|
function getDataView(array) {
|
|
640
674
|
return new DataView(array.buffer);
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
function readUint8Array(reader, offset, size) {
|
|
644
|
-
return reader.readUint8Array(offset, size);
|
|
645
675
|
}
|