@zip.js/zip.js 2.8.33 → 2.8.35
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 +13 -1
- package/deno.json +6 -2
- package/dist/README.md +3 -1
- package/dist/zip-core.js +472 -220
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core.js +449 -220
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-native.js +476 -226
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +478 -228
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +474 -222
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +475 -223
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +477 -225
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +476 -226
- package/index-native.min.js +1 -1
- package/index.cjs +478 -228
- package/index.d.cts +53 -0
- package/index.d.ts +53 -0
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +2 -2
- package/lib/core/codec-worker.js +6 -2
- package/lib/core/configuration.js +22 -1
- package/lib/core/io.js +209 -56
- package/lib/core/streams/aes-crypto-stream.js +1 -10
- package/lib/core/streams/codec-stream.js +36 -15
- package/lib/core/streams/zip-entry-stream.js +19 -28
- package/lib/core/util/array.js +48 -0
- package/lib/core/web-worker-base.js +3 -3
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-fs.js +2 -3
- package/lib/core/zip-reader.js +37 -40
- package/lib/core/zip-writer.js +58 -51
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-core-base.js +5 -3
- package/lib/zip-fs-native.js +2 -2
- package/lib/zip-fs-wasm.js +2 -2
- package/lib/zip-legacy.js +2 -2
- package/lib/zip-module-native.js +2 -2
- package/lib/zip-module-wasm.js +3 -3
- package/lib/zip-native.js +2 -2
- package/lib/zip-wasm.js +2 -2
- package/package.json +3 -3
- package/worker-message-property-names.js +3 -0
- package/.github/workflows/publish.yml +0 -30
- package/reserved-property-names.js +0 -50
package/dist/zip-fs-core.js
CHANGED
|
@@ -161,11 +161,12 @@
|
|
|
161
161
|
workerStarvationTimeout: 5000,
|
|
162
162
|
useWebWorkers: true,
|
|
163
163
|
useCompressionStream: true,
|
|
164
|
+
transferStreams: true,
|
|
164
165
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
165
166
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
166
167
|
};
|
|
167
168
|
|
|
168
|
-
const config =
|
|
169
|
+
const config = { ...DEFAULT_CONFIGURATION };
|
|
169
170
|
|
|
170
171
|
function getConfiguration() {
|
|
171
172
|
return config;
|
|
@@ -175,6 +176,50 @@
|
|
|
175
176
|
return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
|
|
176
177
|
}
|
|
177
178
|
|
|
179
|
+
/*
|
|
180
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
181
|
+
|
|
182
|
+
Redistribution and use in source and binary forms, with or without
|
|
183
|
+
modification, are permitted provided that the following conditions are met:
|
|
184
|
+
|
|
185
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
186
|
+
this list of conditions and the following disclaimer.
|
|
187
|
+
|
|
188
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
189
|
+
notice, this list of conditions and the following disclaimer in
|
|
190
|
+
the documentation and/or other materials provided with the distribution.
|
|
191
|
+
|
|
192
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
193
|
+
derived from this software without specific prior written permission.
|
|
194
|
+
|
|
195
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
196
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
197
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
198
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
199
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
200
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
201
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
202
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
203
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
204
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
function concat(first, second) {
|
|
209
|
+
const result = new Uint8Array(first.length + second.length);
|
|
210
|
+
result.set(first);
|
|
211
|
+
result.set(second, first.length);
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function toExactUint8Array(array) {
|
|
216
|
+
return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function getDataView(array) {
|
|
220
|
+
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
221
|
+
}
|
|
222
|
+
|
|
178
223
|
/*
|
|
179
224
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
180
225
|
|
|
@@ -206,6 +251,7 @@
|
|
|
206
251
|
|
|
207
252
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
208
253
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
254
|
+
const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
|
|
209
255
|
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
210
256
|
const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
|
|
211
257
|
|
|
@@ -216,13 +262,15 @@
|
|
|
216
262
|
const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
|
|
217
263
|
const HTTP_HEADER_RANGE = "Range";
|
|
218
264
|
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
265
|
+
const HTTP_HEADER_ETAG = "Etag";
|
|
266
|
+
const HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
|
|
219
267
|
const HTTP_METHOD_HEAD = "HEAD";
|
|
220
268
|
const HTTP_METHOD_GET = "GET";
|
|
221
269
|
const HTTP_RANGE_UNIT = "bytes";
|
|
222
|
-
const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
|
|
223
270
|
const DEFAULT_BUFFER_SIZE = 256 * 1024;
|
|
224
271
|
|
|
225
272
|
const PROPERTY_NAME_WRITABLE = "writable";
|
|
273
|
+
const DISK_BOUNDARY = Symbol();
|
|
226
274
|
|
|
227
275
|
class Stream {
|
|
228
276
|
|
|
@@ -241,13 +289,13 @@
|
|
|
241
289
|
return this.createReadable();
|
|
242
290
|
}
|
|
243
291
|
|
|
244
|
-
createReadable({ offset = 0, size,
|
|
292
|
+
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
245
293
|
const reader = this;
|
|
246
294
|
let chunkOffset = 0;
|
|
247
295
|
return new ReadableStream({
|
|
248
296
|
async pull(controller) {
|
|
249
297
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
250
|
-
const data = await readUint8Array(reader, offset + chunkOffset, dataSize
|
|
298
|
+
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
251
299
|
controller.enqueue(data);
|
|
252
300
|
if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
253
301
|
controller.close();
|
|
@@ -269,7 +317,7 @@
|
|
|
269
317
|
if (!writer.initialized) {
|
|
270
318
|
throw new Error(ERR_WRITER_NOT_INITIALIZED);
|
|
271
319
|
}
|
|
272
|
-
return writer.writeUint8Array(chunk);
|
|
320
|
+
return writer.writeUint8Array(toExactUint8Array(chunk));
|
|
273
321
|
}
|
|
274
322
|
});
|
|
275
323
|
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
@@ -356,6 +404,27 @@
|
|
|
356
404
|
}
|
|
357
405
|
}
|
|
358
406
|
|
|
407
|
+
let blobSliceReliable;
|
|
408
|
+
let blobSliceProbe;
|
|
409
|
+
|
|
410
|
+
function probeBlobSliceReliability() {
|
|
411
|
+
blobSliceProbe = (async () => {
|
|
412
|
+
try {
|
|
413
|
+
const slicedBlob = new Blob([new Uint8Array(3)]).slice(1, 2);
|
|
414
|
+
const streamReader = slicedBlob.stream().getReader();
|
|
415
|
+
let streamedLength = 0;
|
|
416
|
+
let result = await streamReader.read();
|
|
417
|
+
while (!result.done) {
|
|
418
|
+
streamedLength += result.value.length;
|
|
419
|
+
result = await streamReader.read();
|
|
420
|
+
}
|
|
421
|
+
blobSliceReliable = streamedLength == 1;
|
|
422
|
+
} catch {
|
|
423
|
+
blobSliceReliable = false;
|
|
424
|
+
}
|
|
425
|
+
})();
|
|
426
|
+
}
|
|
427
|
+
|
|
359
428
|
class BlobReader extends Reader {
|
|
360
429
|
|
|
361
430
|
constructor(blob) {
|
|
@@ -364,14 +433,32 @@
|
|
|
364
433
|
blob,
|
|
365
434
|
size: blob.size
|
|
366
435
|
});
|
|
436
|
+
if (!blobSliceProbe) {
|
|
437
|
+
probeBlobSliceReliability();
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
createReadable(options) {
|
|
442
|
+
const reader = this;
|
|
443
|
+
const { blob, size } = reader;
|
|
444
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
445
|
+
if (!offset && readSize >= size) {
|
|
446
|
+
return blob.stream();
|
|
447
|
+
}
|
|
448
|
+
if (blobSliceReliable) {
|
|
449
|
+
return blob.slice(offset, offset + readSize).stream();
|
|
450
|
+
}
|
|
451
|
+
return super.createReadable(options);
|
|
367
452
|
}
|
|
368
453
|
|
|
369
454
|
async readUint8Array(offset, length) {
|
|
370
455
|
const reader = this;
|
|
371
456
|
const offsetEnd = offset + length;
|
|
372
|
-
const
|
|
457
|
+
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
458
|
+
const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
|
|
373
459
|
let arrayBuffer = await blob.arrayBuffer();
|
|
374
|
-
|
|
460
|
+
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
461
|
+
if (sliceIgnoredByBuggyImplementation) {
|
|
375
462
|
arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
|
|
376
463
|
}
|
|
377
464
|
return new Uint8Array(arrayBuffer);
|
|
@@ -452,6 +539,18 @@
|
|
|
452
539
|
super.init();
|
|
453
540
|
}
|
|
454
541
|
|
|
542
|
+
createReadable(options) {
|
|
543
|
+
const reader = this;
|
|
544
|
+
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
545
|
+
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
546
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
547
|
+
if (readSize > 0 && offset < size) {
|
|
548
|
+
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return super.createReadable(options);
|
|
552
|
+
}
|
|
553
|
+
|
|
455
554
|
readUint8Array(index, length) {
|
|
456
555
|
return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
|
|
457
556
|
}
|
|
@@ -480,6 +579,7 @@
|
|
|
480
579
|
useRangeHeader,
|
|
481
580
|
forceRangeRequests,
|
|
482
581
|
combineSizeEocd,
|
|
582
|
+
checkResourceChanges = true,
|
|
483
583
|
fetch
|
|
484
584
|
} = options;
|
|
485
585
|
options = Object.assign({}, options);
|
|
@@ -487,6 +587,7 @@
|
|
|
487
587
|
delete options.useRangeHeader;
|
|
488
588
|
delete options.forceRangeRequests;
|
|
489
589
|
delete options.combineSizeEocd;
|
|
590
|
+
delete options.checkResourceChanges;
|
|
490
591
|
delete options.useXHR;
|
|
491
592
|
delete options.fetch;
|
|
492
593
|
Object.assign(httpReader, {
|
|
@@ -496,6 +597,7 @@
|
|
|
496
597
|
useRangeHeader,
|
|
497
598
|
forceRangeRequests,
|
|
498
599
|
combineSizeEocd,
|
|
600
|
+
checkResourceChanges,
|
|
499
601
|
fetch
|
|
500
602
|
});
|
|
501
603
|
}
|
|
@@ -520,17 +622,8 @@
|
|
|
520
622
|
httpReader.eocdCache = eocdCache;
|
|
521
623
|
}
|
|
522
624
|
}
|
|
523
|
-
|
|
524
|
-
const
|
|
525
|
-
if (contentRangeHeader) {
|
|
526
|
-
const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
|
|
527
|
-
if (splitHeader.length) {
|
|
528
|
-
const headerValue = splitHeader[1];
|
|
529
|
-
if (headerValue && headerValue != "*") {
|
|
530
|
-
contentSize = Number(headerValue);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
625
|
+
setResourceValidators(httpReader, response);
|
|
626
|
+
const contentSize = getContentRangeSize(response);
|
|
534
627
|
if (contentSize === UNDEFINED_VALUE) {
|
|
535
628
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
536
629
|
} else {
|
|
@@ -571,6 +664,8 @@
|
|
|
571
664
|
throw new Error(ERR_HTTP_RANGE);
|
|
572
665
|
}
|
|
573
666
|
}
|
|
667
|
+
checkResourceValidators(httpReader, response);
|
|
668
|
+
setResourceValidators(httpReader, response);
|
|
574
669
|
const data = new Uint8Array(await response.arrayBuffer());
|
|
575
670
|
if (data.length != length) {
|
|
576
671
|
throw new Error(ERR_HTTP_RANGE);
|
|
@@ -582,7 +677,97 @@
|
|
|
582
677
|
if (!data) {
|
|
583
678
|
await getRequestData(httpReader, options);
|
|
584
679
|
}
|
|
585
|
-
return
|
|
680
|
+
return httpReader.data.subarray(index, index + length);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
function createRangeReadable(httpReader, offset, size) {
|
|
685
|
+
let bodyReader;
|
|
686
|
+
let remainingLength = size;
|
|
687
|
+
return new ReadableStream({
|
|
688
|
+
async start() {
|
|
689
|
+
const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, offset, size));
|
|
690
|
+
if (response.status != 206) {
|
|
691
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
692
|
+
}
|
|
693
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
694
|
+
if (contentRangeHeader) {
|
|
695
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
696
|
+
if (!Number.isNaN(rangeStart) && rangeStart != offset) {
|
|
697
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
checkResourceValidators(httpReader, response);
|
|
701
|
+
setResourceValidators(httpReader, response);
|
|
702
|
+
bodyReader = response.body.getReader();
|
|
703
|
+
},
|
|
704
|
+
async pull(controller) {
|
|
705
|
+
const { value, done } = await bodyReader.read();
|
|
706
|
+
if (done) {
|
|
707
|
+
if (remainingLength) {
|
|
708
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
709
|
+
}
|
|
710
|
+
controller.close();
|
|
711
|
+
} else {
|
|
712
|
+
const chunk = value.length > remainingLength ? value.subarray(0, remainingLength) : value;
|
|
713
|
+
remainingLength -= chunk.length;
|
|
714
|
+
if (chunk.length) {
|
|
715
|
+
controller.enqueue(chunk);
|
|
716
|
+
}
|
|
717
|
+
if (!remainingLength) {
|
|
718
|
+
controller.close();
|
|
719
|
+
await bodyReader.cancel();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
},
|
|
723
|
+
cancel(reason) {
|
|
724
|
+
return bodyReader && bodyReader.cancel(reason);
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
function getContentRangeSize(response) {
|
|
730
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
731
|
+
if (contentRangeHeader) {
|
|
732
|
+
const headerValue = contentRangeHeader.trim().split(/\s*\/\s*/)[1];
|
|
733
|
+
if (headerValue && headerValue != "*") {
|
|
734
|
+
const contentSize = Number(headerValue);
|
|
735
|
+
if (!Number.isNaN(contentSize)) {
|
|
736
|
+
return contentSize;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function getResourceValidators({ headers }) {
|
|
743
|
+
return {
|
|
744
|
+
etag: headers.get(HTTP_HEADER_ETAG) || UNDEFINED_VALUE,
|
|
745
|
+
lastModified: headers.get(HTTP_HEADER_LAST_MODIFIED) || UNDEFINED_VALUE
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
function setResourceValidators(httpReader, response) {
|
|
750
|
+
const { checkResourceChanges, resourceValidators } = httpReader;
|
|
751
|
+
if (checkResourceChanges && !resourceValidators && response.status == 206) {
|
|
752
|
+
httpReader.resourceValidators = getResourceValidators(response);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function checkResourceValidators(httpReader, response) {
|
|
757
|
+
const { checkResourceChanges, resourceValidators, size } = httpReader;
|
|
758
|
+
if (checkResourceChanges) {
|
|
759
|
+
const contentRangeSize = getContentRangeSize(response);
|
|
760
|
+
if (contentRangeSize !== UNDEFINED_VALUE && size !== UNDEFINED_VALUE && contentRangeSize != size) {
|
|
761
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
762
|
+
}
|
|
763
|
+
if (resourceValidators) {
|
|
764
|
+
const validators = getResourceValidators(response);
|
|
765
|
+
const changed = Object.entries(resourceValidators).some(([name, value]) =>
|
|
766
|
+
value !== UNDEFINED_VALUE && validators[name] !== UNDEFINED_VALUE && value != validators[name]);
|
|
767
|
+
if (changed) {
|
|
768
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
586
771
|
}
|
|
587
772
|
}
|
|
588
773
|
|
|
@@ -693,6 +878,10 @@
|
|
|
693
878
|
super.init();
|
|
694
879
|
}
|
|
695
880
|
|
|
881
|
+
createReadable(options) {
|
|
882
|
+
return this.reader.createReadable(options);
|
|
883
|
+
}
|
|
884
|
+
|
|
696
885
|
readUint8Array(index, length) {
|
|
697
886
|
return this.reader.readUint8Array(index, length);
|
|
698
887
|
}
|
|
@@ -766,25 +955,26 @@
|
|
|
766
955
|
const reader = this;
|
|
767
956
|
const { readers } = reader;
|
|
768
957
|
reader.lastDiskNumber = 0;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
if (indexDiskReader != readers.length - 1) {
|
|
773
|
-
reader.lastDiskOffset += diskReader.size;
|
|
774
|
-
}
|
|
958
|
+
await Promise.all(readers.map(diskReader => initStream(diskReader)));
|
|
959
|
+
reader.diskOffsets = readers.map(diskReader => {
|
|
960
|
+
const diskOffset = reader.size;
|
|
775
961
|
reader.size += diskReader.size;
|
|
776
|
-
|
|
962
|
+
return diskOffset;
|
|
963
|
+
});
|
|
777
964
|
super.init();
|
|
778
965
|
}
|
|
779
966
|
|
|
780
|
-
|
|
967
|
+
getDiskOffset(diskNumber) {
|
|
968
|
+
const { diskOffsets, size } = this;
|
|
969
|
+
const diskOffset = diskOffsets.at(diskNumber);
|
|
970
|
+
return diskOffset === UNDEFINED_VALUE ? size : diskOffset;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
async readUint8Array(offset, length) {
|
|
781
974
|
const reader = this;
|
|
782
975
|
const { readers } = this;
|
|
783
976
|
let result;
|
|
784
|
-
let currentDiskNumber =
|
|
785
|
-
if (currentDiskNumber == -1) {
|
|
786
|
-
currentDiskNumber = readers.length - 1;
|
|
787
|
-
}
|
|
977
|
+
let currentDiskNumber = 0;
|
|
788
978
|
let currentReaderOffset = offset;
|
|
789
979
|
while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
|
|
790
980
|
currentReaderOffset -= readers[currentDiskNumber].size;
|
|
@@ -797,14 +987,9 @@
|
|
|
797
987
|
result = await readUint8Array(currentReader, currentReaderOffset, length);
|
|
798
988
|
} else {
|
|
799
989
|
const chunkLength = currentReaderSize - currentReaderOffset;
|
|
800
|
-
result = new Uint8Array(length);
|
|
801
990
|
const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength);
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
result.set(secondPart, chunkLength);
|
|
805
|
-
if (firstPart.length + secondPart.length < length) {
|
|
806
|
-
result = result.subarray(0, firstPart.length + secondPart.length);
|
|
807
|
-
}
|
|
991
|
+
const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength);
|
|
992
|
+
result = concat(firstPart, secondPart);
|
|
808
993
|
}
|
|
809
994
|
} else {
|
|
810
995
|
result = EMPTY_UINT8_ARRAY;
|
|
@@ -829,6 +1014,12 @@
|
|
|
829
1014
|
let diskSourceWriter, diskWritable, diskWriter;
|
|
830
1015
|
const writable = new WritableStream({
|
|
831
1016
|
async write(chunk) {
|
|
1017
|
+
if (chunk === DISK_BOUNDARY) {
|
|
1018
|
+
if (diskWriter) {
|
|
1019
|
+
await endDisk();
|
|
1020
|
+
}
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
832
1023
|
const { availableSize } = writer;
|
|
833
1024
|
if (!diskWriter) {
|
|
834
1025
|
const { value, done } = await writerGenerator.next();
|
|
@@ -848,11 +1039,7 @@
|
|
|
848
1039
|
await this.write(chunk);
|
|
849
1040
|
} else if (chunk.length >= availableSize) {
|
|
850
1041
|
await writeChunk(chunk.subarray(0, availableSize));
|
|
851
|
-
await
|
|
852
|
-
writer.diskOffset += diskSourceWriter.size;
|
|
853
|
-
writer.diskNumber++;
|
|
854
|
-
diskWriter = null;
|
|
855
|
-
writer.availableSize = writer.maxSize;
|
|
1042
|
+
await endDisk();
|
|
856
1043
|
if (chunk.length > availableSize) {
|
|
857
1044
|
await this.write(chunk.subarray(availableSize));
|
|
858
1045
|
}
|
|
@@ -863,7 +1050,7 @@
|
|
|
863
1050
|
async close() {
|
|
864
1051
|
if (diskWriter) {
|
|
865
1052
|
await diskWriter.ready;
|
|
866
|
-
await
|
|
1053
|
+
await closeDiskWriter();
|
|
867
1054
|
}
|
|
868
1055
|
},
|
|
869
1056
|
async abort(reason) {
|
|
@@ -888,10 +1075,28 @@
|
|
|
888
1075
|
}
|
|
889
1076
|
}
|
|
890
1077
|
|
|
891
|
-
async function
|
|
1078
|
+
async function endDisk() {
|
|
1079
|
+
await closeDiskWriter();
|
|
1080
|
+
writer.diskOffset += diskSourceWriter.size;
|
|
1081
|
+
writer.diskNumber++;
|
|
1082
|
+
diskWriter = null;
|
|
1083
|
+
writer.availableSize = writer.maxSize;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
async function closeDiskWriter() {
|
|
892
1087
|
await diskWriter.close();
|
|
893
1088
|
}
|
|
894
1089
|
}
|
|
1090
|
+
|
|
1091
|
+
async closeDisk() {
|
|
1092
|
+
const streamWriter = this.writable.getWriter();
|
|
1093
|
+
try {
|
|
1094
|
+
await streamWriter.ready;
|
|
1095
|
+
await streamWriter.write(DISK_BOUNDARY);
|
|
1096
|
+
} finally {
|
|
1097
|
+
streamWriter.releaseLock();
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
895
1100
|
}
|
|
896
1101
|
|
|
897
1102
|
class GenericReader {
|
|
@@ -923,14 +1128,6 @@
|
|
|
923
1128
|
if (writer.size === UNDEFINED_VALUE) {
|
|
924
1129
|
writer.size = 0;
|
|
925
1130
|
}
|
|
926
|
-
if (!(writer instanceof SplitDataWriter)) {
|
|
927
|
-
Object.assign(writer, {
|
|
928
|
-
diskNumber: 0,
|
|
929
|
-
diskOffset: 0,
|
|
930
|
-
availableSize: INFINITY_VALUE,
|
|
931
|
-
maxSize: INFINITY_VALUE
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
1131
|
return writer;
|
|
935
1132
|
}
|
|
936
1133
|
}
|
|
@@ -949,8 +1146,8 @@
|
|
|
949
1146
|
}
|
|
950
1147
|
}
|
|
951
1148
|
|
|
952
|
-
function readUint8Array(reader, offset, size
|
|
953
|
-
return reader.readUint8Array(offset, size
|
|
1149
|
+
function readUint8Array(reader, offset, size) {
|
|
1150
|
+
return reader.readUint8Array(offset, size);
|
|
954
1151
|
}
|
|
955
1152
|
|
|
956
1153
|
/*
|
|
@@ -2239,16 +2436,6 @@
|
|
|
2239
2436
|
}
|
|
2240
2437
|
}
|
|
2241
2438
|
|
|
2242
|
-
function concat(leftArray, rightArray) {
|
|
2243
|
-
let array = leftArray;
|
|
2244
|
-
if (leftArray.length + rightArray.length) {
|
|
2245
|
-
array = new Uint8Array(leftArray.length + rightArray.length);
|
|
2246
|
-
array.set(leftArray, 0);
|
|
2247
|
-
array.set(rightArray, leftArray.length);
|
|
2248
|
-
}
|
|
2249
|
-
return array;
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
2439
|
function expand(inputArray, length) {
|
|
2253
2440
|
if (length && length > inputArray.length) {
|
|
2254
2441
|
const array = inputArray;
|
|
@@ -2510,44 +2697,34 @@
|
|
|
2510
2697
|
constructor() {
|
|
2511
2698
|
// deno-lint-ignore prefer-const
|
|
2512
2699
|
let stream;
|
|
2513
|
-
let
|
|
2514
|
-
let
|
|
2700
|
+
let headerBytesLeft = GZIP_HEADER_LENGTH;
|
|
2701
|
+
let trailerCandidate = new Uint8Array(0);
|
|
2515
2702
|
super({
|
|
2516
2703
|
transform(chunk, controller) {
|
|
2517
|
-
if (
|
|
2518
|
-
const
|
|
2519
|
-
|
|
2520
|
-
chunk = chunk.subarray(
|
|
2704
|
+
if (headerBytesLeft) {
|
|
2705
|
+
const droppedLength = Math.min(headerBytesLeft, chunk.length);
|
|
2706
|
+
headerBytesLeft -= droppedLength;
|
|
2707
|
+
chunk = chunk.subarray(droppedLength);
|
|
2521
2708
|
if (!chunk.length) {
|
|
2522
2709
|
return;
|
|
2523
2710
|
}
|
|
2524
2711
|
}
|
|
2525
|
-
const
|
|
2526
|
-
if (
|
|
2527
|
-
|
|
2528
|
-
pending.set(tail);
|
|
2529
|
-
pending.set(chunk, tail.length);
|
|
2530
|
-
tail = pending;
|
|
2712
|
+
const availableLength = trailerCandidate.length + chunk.length;
|
|
2713
|
+
if (availableLength <= GZIP_TRAILER_LENGTH) {
|
|
2714
|
+
trailerCandidate = concat(trailerCandidate, chunk);
|
|
2531
2715
|
return;
|
|
2532
2716
|
}
|
|
2533
|
-
const emitLength =
|
|
2534
|
-
const
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
const nextTail = new Uint8Array(GZIP_TRAILER_LENGTH);
|
|
2542
|
-
const tailRemaining = tail.length - fromTail;
|
|
2543
|
-
if (tailRemaining) {
|
|
2544
|
-
nextTail.set(tail.subarray(fromTail), 0);
|
|
2545
|
-
}
|
|
2546
|
-
nextTail.set(chunk.subarray(emitLength - fromTail), tailRemaining);
|
|
2547
|
-
tail = nextTail;
|
|
2717
|
+
const emitLength = availableLength - GZIP_TRAILER_LENGTH;
|
|
2718
|
+
const emittedFromTrailer = Math.min(emitLength, trailerCandidate.length);
|
|
2719
|
+
controller.enqueue(concat(
|
|
2720
|
+
trailerCandidate.subarray(0, emittedFromTrailer),
|
|
2721
|
+
chunk.subarray(0, emitLength - emittedFromTrailer)));
|
|
2722
|
+
trailerCandidate = concat(
|
|
2723
|
+
trailerCandidate.subarray(emittedFromTrailer),
|
|
2724
|
+
chunk.subarray(emitLength - emittedFromTrailer));
|
|
2548
2725
|
},
|
|
2549
2726
|
flush() {
|
|
2550
|
-
const dataView =
|
|
2727
|
+
const dataView = getDataView(trailerCandidate);
|
|
2551
2728
|
stream.signature = dataView.getUint32(0, true);
|
|
2552
2729
|
stream.uncompressedSize = dataView.getUint32(4, true);
|
|
2553
2730
|
}
|
|
@@ -2790,33 +2967,54 @@
|
|
|
2790
2967
|
class ChunkStream extends TransformStream {
|
|
2791
2968
|
|
|
2792
2969
|
constructor(chunkSize) {
|
|
2793
|
-
|
|
2970
|
+
const pendingChunks = [];
|
|
2971
|
+
let pendingLength = 0;
|
|
2794
2972
|
if (!(chunkSize >= 1)) {
|
|
2795
2973
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2796
2974
|
}
|
|
2797
2975
|
super({
|
|
2798
|
-
transform,
|
|
2976
|
+
transform(chunk, controller) {
|
|
2977
|
+
pendingChunks.push(chunk);
|
|
2978
|
+
pendingLength += chunk.length;
|
|
2979
|
+
while (pendingLength > chunkSize) {
|
|
2980
|
+
controller.enqueue(shiftChunk());
|
|
2981
|
+
}
|
|
2982
|
+
},
|
|
2799
2983
|
flush(controller) {
|
|
2800
|
-
if (
|
|
2801
|
-
controller.enqueue(
|
|
2984
|
+
if (pendingLength) {
|
|
2985
|
+
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2802
2986
|
}
|
|
2803
2987
|
}
|
|
2804
2988
|
});
|
|
2805
2989
|
|
|
2806
|
-
function
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2990
|
+
function shiftChunk() {
|
|
2991
|
+
const result = new Uint8Array(chunkSize);
|
|
2992
|
+
let resultOffset = 0;
|
|
2993
|
+
while (resultOffset < chunkSize) {
|
|
2994
|
+
const firstChunk = pendingChunks[0];
|
|
2995
|
+
const remainingLength = chunkSize - resultOffset;
|
|
2996
|
+
if (firstChunk.length <= remainingLength) {
|
|
2997
|
+
result.set(firstChunk, resultOffset);
|
|
2998
|
+
resultOffset += firstChunk.length;
|
|
2999
|
+
pendingChunks.shift();
|
|
3000
|
+
} else {
|
|
3001
|
+
result.set(firstChunk.subarray(0, remainingLength), resultOffset);
|
|
3002
|
+
pendingChunks[0] = firstChunk.subarray(remainingLength);
|
|
3003
|
+
resultOffset += remainingLength;
|
|
3004
|
+
}
|
|
2813
3005
|
}
|
|
3006
|
+
pendingLength -= chunkSize;
|
|
3007
|
+
return result;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
function concatChunks(chunks, length) {
|
|
3011
|
+
const result = new Uint8Array(length);
|
|
2814
3012
|
let offset = 0;
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
offset +=
|
|
3013
|
+
for (const chunk of chunks) {
|
|
3014
|
+
result.set(chunk, offset);
|
|
3015
|
+
offset += chunk.length;
|
|
2818
3016
|
}
|
|
2819
|
-
|
|
3017
|
+
return result;
|
|
2820
3018
|
}
|
|
2821
3019
|
}
|
|
2822
3020
|
}
|
|
@@ -2998,7 +3196,10 @@
|
|
|
2998
3196
|
}
|
|
2999
3197
|
}
|
|
3000
3198
|
codecStream = new CodecStream(options, config);
|
|
3001
|
-
await readable
|
|
3199
|
+
await readable
|
|
3200
|
+
.pipeThrough(codecStream)
|
|
3201
|
+
.pipeThrough(new ChunkStream(getChunkSize(config)))
|
|
3202
|
+
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
3002
3203
|
const {
|
|
3003
3204
|
signature,
|
|
3004
3205
|
inputSize,
|
|
@@ -3197,7 +3398,7 @@
|
|
|
3197
3398
|
const { value, readable, writable } = message;
|
|
3198
3399
|
const transferables = [];
|
|
3199
3400
|
if (value) {
|
|
3200
|
-
message.value =
|
|
3401
|
+
message.value = toExactUint8Array(value);
|
|
3201
3402
|
transferables.push(message.value.buffer);
|
|
3202
3403
|
}
|
|
3203
3404
|
if (transferStreams && transferStreamsSupported) {
|
|
@@ -3321,8 +3522,8 @@
|
|
|
3321
3522
|
const { options, config } = workerOptions;
|
|
3322
3523
|
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
3323
3524
|
const { workerURI, maxWorkers } = config;
|
|
3324
|
-
workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
|
|
3325
|
-
const streamCopy = !compressed && !signed && !encrypted
|
|
3525
|
+
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
3526
|
+
const streamCopy = !compressed && !signed && !encrypted;
|
|
3326
3527
|
workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
3327
3528
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
3328
3529
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
@@ -3791,7 +3992,7 @@
|
|
|
3791
3992
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
3792
3993
|
if (!endOfDirectoryInfo) {
|
|
3793
3994
|
const signatureArray = await readUint8Array(reader, 0, 4);
|
|
3794
|
-
const signatureView = getDataView
|
|
3995
|
+
const signatureView = getDataView(signatureArray);
|
|
3795
3996
|
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
3796
3997
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
3797
3998
|
} else {
|
|
@@ -3801,7 +4002,7 @@
|
|
|
3801
4002
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
3802
4003
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
3803
4004
|
}
|
|
3804
|
-
const endOfDirectoryView = getDataView
|
|
4005
|
+
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
3805
4006
|
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
3806
4007
|
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
3807
4008
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
@@ -3817,17 +4018,21 @@
|
|
|
3817
4018
|
let prependedDataLength = 0;
|
|
3818
4019
|
let startOffset;
|
|
3819
4020
|
let zip64EndOfDirectory;
|
|
3820
|
-
|
|
4021
|
+
const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
|
|
4022
|
+
if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
|
|
4023
|
+
directoryDataOffset += getDiskOffset$1(reader, diskNumber);
|
|
4024
|
+
}
|
|
4025
|
+
if (requiresZip64) {
|
|
3821
4026
|
const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
|
|
3822
4027
|
await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
|
|
3823
4028
|
EMPTY_UINT8_ARRAY;
|
|
3824
|
-
const endOfDirectoryLocatorView = getDataView
|
|
4029
|
+
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
3825
4030
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
3826
4031
|
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
3827
|
-
directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
|
|
3828
|
-
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
3829
|
-
let endOfDirectoryView = getDataView
|
|
3830
|
-
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
4032
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4033
|
+
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4034
|
+
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4035
|
+
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
3831
4036
|
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
3832
4037
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
3833
4038
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3835,8 +4040,8 @@
|
|
|
3835
4040
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3836
4041
|
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
3837
4042
|
}
|
|
3838
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
3839
|
-
endOfDirectoryView = getDataView
|
|
4043
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4044
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
3840
4045
|
}
|
|
3841
4046
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
3842
4047
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -3862,7 +4067,7 @@
|
|
|
3862
4067
|
} else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
3863
4068
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
3864
4069
|
}
|
|
3865
|
-
directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4070
|
+
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
3866
4071
|
}
|
|
3867
4072
|
}
|
|
3868
4073
|
const declaredDirectoryDataLength = directoryDataLength;
|
|
@@ -3879,19 +4084,19 @@
|
|
|
3879
4084
|
throw new Error(ERR_BAD_FORMAT);
|
|
3880
4085
|
}
|
|
3881
4086
|
let offset = 0;
|
|
3882
|
-
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3883
|
-
let directoryView = getDataView
|
|
4087
|
+
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4088
|
+
let directoryView = getDataView(directoryArray);
|
|
3884
4089
|
if (directoryDataLength) {
|
|
3885
4090
|
if (directoryArray.length < 4) {
|
|
3886
4091
|
throw new Error(ERR_BAD_FORMAT);
|
|
3887
4092
|
}
|
|
3888
|
-
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength
|
|
4093
|
+
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
3889
4094
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
3890
4095
|
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3891
4096
|
let reconcile = !storedPointsAtDirectory;
|
|
3892
4097
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
3893
|
-
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4
|
|
3894
|
-
reconcile = getUint32(getDataView
|
|
4098
|
+
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4099
|
+
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3895
4100
|
}
|
|
3896
4101
|
if (reconcile) {
|
|
3897
4102
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3899,16 +4104,16 @@
|
|
|
3899
4104
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3900
4105
|
prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
|
|
3901
4106
|
}
|
|
3902
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3903
|
-
directoryView = getDataView
|
|
4107
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4108
|
+
directoryView = getDataView(directoryArray);
|
|
3904
4109
|
}
|
|
3905
4110
|
}
|
|
3906
4111
|
}
|
|
3907
|
-
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset
|
|
4112
|
+
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
3908
4113
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
3909
4114
|
directoryDataLength = expectedDirectoryDataLength;
|
|
3910
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3911
|
-
directoryView = getDataView
|
|
4115
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4116
|
+
directoryView = getDataView(directoryArray);
|
|
3912
4117
|
}
|
|
3913
4118
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
3914
4119
|
throw new Error(ERR_BAD_FORMAT);
|
|
@@ -3981,7 +4186,7 @@
|
|
|
3981
4186
|
});
|
|
3982
4187
|
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
|
|
3983
4188
|
fileEntry.offset += prependedDataLength;
|
|
3984
|
-
startOffset = Math.min(fileEntry.offset, startOffset);
|
|
4189
|
+
startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
|
|
3985
4190
|
if (checkAmbiguity) {
|
|
3986
4191
|
if (filenames.has(fileEntry.filename)) {
|
|
3987
4192
|
duplicateFilename = true;
|
|
@@ -4095,8 +4300,9 @@
|
|
|
4095
4300
|
dataDescriptor
|
|
4096
4301
|
} = bitFlag;
|
|
4097
4302
|
const localDirectory = fileEntry.localDirectory = {};
|
|
4098
|
-
const
|
|
4099
|
-
const
|
|
4303
|
+
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
4304
|
+
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
4305
|
+
const dataView = getDataView(dataArray);
|
|
4100
4306
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
4101
4307
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
4102
4308
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
@@ -4121,12 +4327,12 @@
|
|
|
4121
4327
|
const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
|
|
4122
4328
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
4123
4329
|
if (checkAmbiguity && (filenameLength || extraFieldLength)) {
|
|
4124
|
-
const trailingDataArray = await readUint8Array(reader,
|
|
4330
|
+
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
4125
4331
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
4126
4332
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
4127
4333
|
} else {
|
|
4128
4334
|
localDirectory.rawExtraField = extraFieldLength ?
|
|
4129
|
-
await readUint8Array(reader,
|
|
4335
|
+
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
4130
4336
|
EMPTY_UINT8_ARRAY;
|
|
4131
4337
|
}
|
|
4132
4338
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
@@ -4152,9 +4358,9 @@
|
|
|
4152
4358
|
throw new Error(ERR_ENCRYPTED);
|
|
4153
4359
|
}
|
|
4154
4360
|
}
|
|
4155
|
-
const dataOffset =
|
|
4361
|
+
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4156
4362
|
const size = compressedSize;
|
|
4157
|
-
const readable = reader.createReadable({ offset: dataOffset, size
|
|
4363
|
+
const readable = reader.createReadable({ offset: dataOffset, size });
|
|
4158
4364
|
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
4159
4365
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
4160
4366
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -4195,8 +4401,7 @@
|
|
|
4195
4401
|
reader,
|
|
4196
4402
|
fileEntry,
|
|
4197
4403
|
index,
|
|
4198
|
-
offset,
|
|
4199
|
-
diskNumberStart,
|
|
4404
|
+
offset: localHeaderOffset,
|
|
4200
4405
|
signature,
|
|
4201
4406
|
compressedSize,
|
|
4202
4407
|
uncompressedSize,
|
|
@@ -4260,7 +4465,7 @@
|
|
|
4260
4465
|
function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
|
|
4261
4466
|
const { rawExtraField } = directory;
|
|
4262
4467
|
const extraField = directory.extraField = new Map();
|
|
4263
|
-
const rawExtraFieldView = getDataView
|
|
4468
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
4264
4469
|
let offsetExtraField = 0;
|
|
4265
4470
|
try {
|
|
4266
4471
|
while (offsetExtraField < rawExtraField.length) {
|
|
@@ -4332,7 +4537,7 @@
|
|
|
4332
4537
|
|
|
4333
4538
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
4334
4539
|
directory.zip64 = true;
|
|
4335
|
-
const extraFieldView = getDataView
|
|
4540
|
+
const extraFieldView = getDataView(extraFieldZip64.data);
|
|
4336
4541
|
const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
|
|
4337
4542
|
const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
|
|
4338
4543
|
if (extraFieldZip64.data.length < requiredLength) {
|
|
@@ -4351,10 +4556,10 @@
|
|
|
4351
4556
|
extraFieldUnicode.valid = false;
|
|
4352
4557
|
return;
|
|
4353
4558
|
}
|
|
4354
|
-
const extraFieldView = getDataView
|
|
4559
|
+
const extraFieldView = getDataView(extraFieldUnicode.data);
|
|
4355
4560
|
const crc32 = new Crc32();
|
|
4356
4561
|
crc32.append(fileEntry[rawPropertyName]);
|
|
4357
|
-
const dataViewSignature = getDataView
|
|
4562
|
+
const dataViewSignature = getDataView(new Uint8Array(4));
|
|
4358
4563
|
dataViewSignature.setUint32(0, crc32.get(), true);
|
|
4359
4564
|
const signature = getUint32(extraFieldView, 1);
|
|
4360
4565
|
Object.assign(extraFieldUnicode, {
|
|
@@ -4369,7 +4574,7 @@
|
|
|
4369
4574
|
}
|
|
4370
4575
|
|
|
4371
4576
|
function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
|
|
4372
|
-
const extraFieldView = getDataView
|
|
4577
|
+
const extraFieldView = getDataView(extraFieldAES.data);
|
|
4373
4578
|
const strength = getUint8(extraFieldView, 4);
|
|
4374
4579
|
Object.assign(extraFieldAES, {
|
|
4375
4580
|
vendorVersion: getUint8(extraFieldView, 0),
|
|
@@ -4382,7 +4587,7 @@
|
|
|
4382
4587
|
}
|
|
4383
4588
|
|
|
4384
4589
|
function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
4385
|
-
const extraFieldView = getDataView
|
|
4590
|
+
const extraFieldView = getDataView(extraFieldNTFS.data);
|
|
4386
4591
|
let offsetExtraField = 4;
|
|
4387
4592
|
let tag1Data;
|
|
4388
4593
|
try {
|
|
@@ -4399,7 +4604,7 @@
|
|
|
4399
4604
|
}
|
|
4400
4605
|
try {
|
|
4401
4606
|
if (tag1Data && tag1Data.length == 24) {
|
|
4402
|
-
const tag1View = getDataView
|
|
4607
|
+
const tag1View = getDataView(tag1Data);
|
|
4403
4608
|
const rawLastModDate = tag1View.getBigUint64(0, true);
|
|
4404
4609
|
const rawLastAccessDate = tag1View.getBigUint64(8, true);
|
|
4405
4610
|
const rawCreationDate = tag1View.getBigUint64(16, true);
|
|
@@ -4422,7 +4627,7 @@
|
|
|
4422
4627
|
|
|
4423
4628
|
function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
4424
4629
|
try {
|
|
4425
|
-
const view = getDataView
|
|
4630
|
+
const view = getDataView(extraField.data);
|
|
4426
4631
|
let uid, gid;
|
|
4427
4632
|
if (isInfoZip) {
|
|
4428
4633
|
let offset = 0;
|
|
@@ -4460,7 +4665,7 @@
|
|
|
4460
4665
|
if (!extraFieldExtendedTimestamp.data.length) {
|
|
4461
4666
|
return;
|
|
4462
4667
|
}
|
|
4463
|
-
const extraFieldView = getDataView
|
|
4668
|
+
const extraFieldView = getDataView(extraFieldExtendedTimestamp.data);
|
|
4464
4669
|
const flags = getUint8(extraFieldView, 0);
|
|
4465
4670
|
const timeProperties = [];
|
|
4466
4671
|
const timeRawProperties = [];
|
|
@@ -4498,7 +4703,6 @@
|
|
|
4498
4703
|
fileEntry,
|
|
4499
4704
|
index,
|
|
4500
4705
|
offset,
|
|
4501
|
-
diskNumberStart,
|
|
4502
4706
|
signature,
|
|
4503
4707
|
compressedSize,
|
|
4504
4708
|
uncompressedSize,
|
|
@@ -4507,12 +4711,6 @@
|
|
|
4507
4711
|
extraFieldZip64,
|
|
4508
4712
|
readRanges
|
|
4509
4713
|
}) {
|
|
4510
|
-
let diskOffset = 0;
|
|
4511
|
-
if (diskNumberStart && reader.readers) {
|
|
4512
|
-
for (let indexReader = 0; indexReader < Math.min(diskNumberStart, reader.readers.length); indexReader++) {
|
|
4513
|
-
diskOffset += reader.readers[indexReader].size;
|
|
4514
|
-
}
|
|
4515
|
-
}
|
|
4516
4714
|
let dataDescriptorLength = 0;
|
|
4517
4715
|
if (dataDescriptor) {
|
|
4518
4716
|
if (extraFieldZip64) {
|
|
@@ -4522,19 +4720,19 @@
|
|
|
4522
4720
|
}
|
|
4523
4721
|
}
|
|
4524
4722
|
if (dataDescriptorLength) {
|
|
4525
|
-
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH
|
|
4723
|
+
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
4526
4724
|
const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
4527
|
-
getUint32(getDataView
|
|
4725
|
+
getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
4528
4726
|
if (dataDescriptorSignature) {
|
|
4529
|
-
const readSignature = getUint32(getDataView
|
|
4727
|
+
const readSignature = getUint32(getDataView(dataDescriptorArray), 4);
|
|
4530
4728
|
let readCompressedSize;
|
|
4531
4729
|
let readUncompressedSize;
|
|
4532
4730
|
if (extraFieldZip64) {
|
|
4533
|
-
readCompressedSize = getBigUint64(getDataView
|
|
4534
|
-
readUncompressedSize = getBigUint64(getDataView
|
|
4731
|
+
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
4732
|
+
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
4535
4733
|
} else {
|
|
4536
|
-
readCompressedSize = getUint32(getDataView
|
|
4537
|
-
readUncompressedSize = getUint32(getDataView
|
|
4734
|
+
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
4735
|
+
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
4538
4736
|
}
|
|
4539
4737
|
const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
|
|
4540
4738
|
if (matchSignature &&
|
|
@@ -4545,8 +4743,8 @@
|
|
|
4545
4743
|
}
|
|
4546
4744
|
}
|
|
4547
4745
|
const range = {
|
|
4548
|
-
start:
|
|
4549
|
-
end:
|
|
4746
|
+
start: offset,
|
|
4747
|
+
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
4550
4748
|
fileEntry
|
|
4551
4749
|
};
|
|
4552
4750
|
for (const [otherIndex, otherRange] of readRanges) {
|
|
@@ -4559,6 +4757,10 @@
|
|
|
4559
4757
|
readRanges.set(index, range);
|
|
4560
4758
|
}
|
|
4561
4759
|
|
|
4760
|
+
function getDiskOffset$1(reader, diskNumber) {
|
|
4761
|
+
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
4762
|
+
}
|
|
4763
|
+
|
|
4562
4764
|
function getStrictness(strictness, checkAmbiguity) {
|
|
4563
4765
|
if (strictness === UNDEFINED_VALUE) {
|
|
4564
4766
|
return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
|
|
@@ -4642,7 +4844,7 @@
|
|
|
4642
4844
|
async function* scanEndOfCentralDirectory(reader, scanLength) {
|
|
4643
4845
|
const scanOffset = reader.size - scanLength;
|
|
4644
4846
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
4645
|
-
const scanView = getDataView
|
|
4847
|
+
const scanView = getDataView(scanArray);
|
|
4646
4848
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
4647
4849
|
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4648
4850
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
@@ -4665,7 +4867,8 @@
|
|
|
4665
4867
|
if (!filesLength && !directoryDataLength) {
|
|
4666
4868
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
4667
4869
|
}
|
|
4668
|
-
|
|
4870
|
+
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
4871
|
+
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
4669
4872
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4670
4873
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
4671
4874
|
}
|
|
@@ -4683,7 +4886,7 @@
|
|
|
4683
4886
|
if (remoteProbeBudget.count > 0) {
|
|
4684
4887
|
remoteProbeBudget.count--;
|
|
4685
4888
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
4686
|
-
return getUint32(getDataView
|
|
4889
|
+
return getUint32(getDataView(signatureArray), 0);
|
|
4687
4890
|
}
|
|
4688
4891
|
return UNDEFINED_VALUE;
|
|
4689
4892
|
}
|
|
@@ -4748,9 +4951,26 @@
|
|
|
4748
4951
|
return Number(view.getBigUint64(offset, true));
|
|
4749
4952
|
}
|
|
4750
4953
|
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4954
|
+
var zipReader = /*#__PURE__*/Object.freeze({
|
|
4955
|
+
__proto__: null,
|
|
4956
|
+
ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
|
|
4957
|
+
ERR_BAD_FORMAT: ERR_BAD_FORMAT,
|
|
4958
|
+
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
4959
|
+
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
4960
|
+
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
4961
|
+
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
4962
|
+
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
4963
|
+
ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
|
|
4964
|
+
ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
|
|
4965
|
+
ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
|
|
4966
|
+
ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
|
|
4967
|
+
ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
|
|
4968
|
+
ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
|
|
4969
|
+
ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
|
|
4970
|
+
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
4971
|
+
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
4972
|
+
ZipReader: ZipReader
|
|
4973
|
+
});
|
|
4754
4974
|
|
|
4755
4975
|
/*
|
|
4756
4976
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -4815,9 +5035,10 @@
|
|
|
4815
5035
|
|
|
4816
5036
|
constructor(writer, options = {}) {
|
|
4817
5037
|
writer = new GenericWriter(writer);
|
|
5038
|
+
const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
|
|
4818
5039
|
const addSplitZipSignature =
|
|
4819
|
-
|
|
4820
|
-
|
|
5040
|
+
availableSize > 0 && availableSize !== INFINITY_VALUE &&
|
|
5041
|
+
maxSize > 0 && maxSize !== INFINITY_VALUE;
|
|
4821
5042
|
Object.assign(this, {
|
|
4822
5043
|
writer,
|
|
4823
5044
|
addSplitZipSignature,
|
|
@@ -4839,9 +5060,10 @@
|
|
|
4839
5060
|
}
|
|
4840
5061
|
reader = new GenericReader(reader);
|
|
4841
5062
|
await initStream(reader);
|
|
4842
|
-
const
|
|
4843
|
-
const
|
|
4844
|
-
await zipReader.
|
|
5063
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5064
|
+
const zipReader$1 = new ZipReader(reader.readable);
|
|
5065
|
+
const entries = await zipReader$1.getEntries();
|
|
5066
|
+
await zipReader$1.close();
|
|
4845
5067
|
await initStream(this.writer);
|
|
4846
5068
|
await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
|
|
4847
5069
|
this.writer.size = this.offset = reader.size;
|
|
@@ -4857,8 +5079,6 @@
|
|
|
4857
5079
|
encrypted,
|
|
4858
5080
|
uncompressedSize,
|
|
4859
5081
|
compressedSize,
|
|
4860
|
-
diskOffset,
|
|
4861
|
-
diskNumber,
|
|
4862
5082
|
zip64
|
|
4863
5083
|
} = entry;
|
|
4864
5084
|
let {
|
|
@@ -4906,8 +5126,9 @@
|
|
|
4906
5126
|
Object.assign(entry, {
|
|
4907
5127
|
zip64UncompressedSize,
|
|
4908
5128
|
zip64CompressedSize,
|
|
4909
|
-
zip64Offset: zip64 &&
|
|
4910
|
-
|
|
5129
|
+
zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
|
|
5130
|
+
diskNumberStart: 0,
|
|
5131
|
+
zip64DiskNumberStart: false,
|
|
4911
5132
|
rawExtraFieldZip64,
|
|
4912
5133
|
rawExtraFieldAES,
|
|
4913
5134
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -5012,7 +5233,8 @@
|
|
|
5012
5233
|
try {
|
|
5013
5234
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
5014
5235
|
({ reader } = sizesInfo);
|
|
5015
|
-
const
|
|
5236
|
+
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
5237
|
+
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
5016
5238
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
5017
5239
|
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
5018
5240
|
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
@@ -5189,7 +5411,7 @@
|
|
|
5189
5411
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
5190
5412
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
5191
5413
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5192
|
-
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS
|
|
5414
|
+
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
5193
5415
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
5194
5416
|
const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
5195
5417
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
@@ -5387,7 +5609,7 @@
|
|
|
5387
5609
|
await requestLockWriter();
|
|
5388
5610
|
}
|
|
5389
5611
|
await initStream(fileWriter);
|
|
5390
|
-
const
|
|
5612
|
+
const diskOffset = getDiskOffset(writer);
|
|
5391
5613
|
if (zipWriter.addSplitZipSignature) {
|
|
5392
5614
|
delete zipWriter.addSplitZipSignature;
|
|
5393
5615
|
const signatureArray = new Uint8Array(4);
|
|
@@ -5404,7 +5626,7 @@
|
|
|
5404
5626
|
await lockPreviousFileEntry;
|
|
5405
5627
|
await skipDiskIfNeeded();
|
|
5406
5628
|
}
|
|
5407
|
-
const diskNumberStart = writer
|
|
5629
|
+
const diskNumberStart = getDiskNumber(writer);
|
|
5408
5630
|
const entryOffset = getSegmentOffset(zipWriter, writer);
|
|
5409
5631
|
fileEntry.diskNumberStart = diskNumberStart;
|
|
5410
5632
|
if (!bufferedWrite) {
|
|
@@ -5424,11 +5646,11 @@
|
|
|
5424
5646
|
writingBufferedEntryData = true;
|
|
5425
5647
|
writerSizeBeforeEntry = writer.size;
|
|
5426
5648
|
await skipDiskIfNeeded();
|
|
5427
|
-
fileEntry.diskNumberStart = writer
|
|
5649
|
+
fileEntry.diskNumberStart = getDiskNumber(writer);
|
|
5428
5650
|
fileEntry.offset = getSegmentOffset(zipWriter, writer);
|
|
5429
5651
|
if (usdz) {
|
|
5430
5652
|
const previousMetadataSize = entryInfo.metadataSize;
|
|
5431
|
-
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer
|
|
5653
|
+
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
|
|
5432
5654
|
fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
|
|
5433
5655
|
}
|
|
5434
5656
|
updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
|
|
@@ -5493,9 +5715,8 @@
|
|
|
5493
5715
|
}
|
|
5494
5716
|
|
|
5495
5717
|
async function skipDiskIfNeeded() {
|
|
5496
|
-
if (getLength(headerInfo.localHeaderArray)
|
|
5497
|
-
writer.
|
|
5498
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
5718
|
+
if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
|
|
5719
|
+
await writer.closeDisk();
|
|
5499
5720
|
}
|
|
5500
5721
|
}
|
|
5501
5722
|
}
|
|
@@ -5606,7 +5827,7 @@
|
|
|
5606
5827
|
}
|
|
5607
5828
|
const { writable } = writer;
|
|
5608
5829
|
if (reader) {
|
|
5609
|
-
const readable = reader.createReadable ? reader.createReadable(
|
|
5830
|
+
const readable = reader.createReadable ? reader.createReadable() : reader.readable;
|
|
5610
5831
|
const size = reader.size;
|
|
5611
5832
|
const workerOptions = {
|
|
5612
5833
|
options: {
|
|
@@ -6038,8 +6259,8 @@
|
|
|
6038
6259
|
|
|
6039
6260
|
async function closeFile(zipWriter, comment, options) {
|
|
6040
6261
|
const directoryDataLength = createDirectoryRecords(zipWriter.files);
|
|
6041
|
-
const
|
|
6042
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, {
|
|
6262
|
+
const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6263
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
|
|
6043
6264
|
}
|
|
6044
6265
|
|
|
6045
6266
|
function createDirectoryRecords(files) {
|
|
@@ -6121,8 +6342,8 @@
|
|
|
6121
6342
|
await initStream(writer);
|
|
6122
6343
|
let offset = 0;
|
|
6123
6344
|
let directoryDiskOffset = 0;
|
|
6124
|
-
let
|
|
6125
|
-
let
|
|
6345
|
+
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
6346
|
+
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
6126
6347
|
for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
|
|
6127
6348
|
const {
|
|
6128
6349
|
offset: fileEntryOffset,
|
|
@@ -6149,15 +6370,14 @@
|
|
|
6149
6370
|
} = fileEntry;
|
|
6150
6371
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6151
6372
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
6152
|
-
if (offset + directoryRecordLength - directoryDiskOffset
|
|
6373
|
+
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
6153
6374
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
6154
6375
|
directoryDiskOffset = offset;
|
|
6155
|
-
writer.
|
|
6156
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
6376
|
+
await writer.closeDisk();
|
|
6157
6377
|
}
|
|
6158
6378
|
if (indexFileEntry == 0) {
|
|
6159
|
-
|
|
6160
|
-
|
|
6379
|
+
directoryStartDiskNumber = getDiskNumber(writer);
|
|
6380
|
+
directoryStartDiskOffset = getDiskOffset(writer);
|
|
6161
6381
|
}
|
|
6162
6382
|
if (!zip64UncompressedSize) {
|
|
6163
6383
|
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
|
|
@@ -6197,18 +6417,18 @@
|
|
|
6197
6417
|
}
|
|
6198
6418
|
}
|
|
6199
6419
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
6200
|
-
return {
|
|
6420
|
+
return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
|
|
6201
6421
|
}
|
|
6202
6422
|
|
|
6203
6423
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
6204
6424
|
const { writer } = zipWriter;
|
|
6205
|
-
const {
|
|
6425
|
+
const { directoryStart } = cdInfo;
|
|
6206
6426
|
let { directoryDataLength } = cdInfo;
|
|
6207
6427
|
let filesLength = zipWriter.files.size;
|
|
6208
|
-
let diskNumber =
|
|
6209
|
-
let directoryOffset =
|
|
6210
|
-
let lastDiskNumber = writer
|
|
6211
|
-
if (writer
|
|
6428
|
+
let diskNumber = directoryStart.diskNumber;
|
|
6429
|
+
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
6430
|
+
let lastDiskNumber = getDiskNumber(writer);
|
|
6431
|
+
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
6212
6432
|
lastDiskNumber++;
|
|
6213
6433
|
}
|
|
6214
6434
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
@@ -6224,11 +6444,10 @@
|
|
|
6224
6444
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6225
6445
|
}
|
|
6226
6446
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
6227
|
-
if (getLength(endOfdirectoryRecord.array) + commentLength
|
|
6228
|
-
writer.
|
|
6229
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
6447
|
+
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
6448
|
+
await writer.closeDisk();
|
|
6230
6449
|
}
|
|
6231
|
-
lastDiskNumber = writer
|
|
6450
|
+
lastDiskNumber = getDiskNumber(writer);
|
|
6232
6451
|
if (zip64) {
|
|
6233
6452
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
6234
6453
|
endOfdirectoryRecord.uint64(44);
|
|
@@ -6242,7 +6461,7 @@
|
|
|
6242
6461
|
endOfdirectoryRecord.uint64(directoryOffset);
|
|
6243
6462
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
6244
6463
|
endOfdirectoryRecord.uint32(lastDiskNumber);
|
|
6245
|
-
endOfdirectoryRecord.uint64(BigInt(zipWriter
|
|
6464
|
+
endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
|
|
6246
6465
|
endOfdirectoryRecord.uint32(lastDiskNumber + 1);
|
|
6247
6466
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
6248
6467
|
if (supportZip64SplitFile) {
|
|
@@ -6282,8 +6501,23 @@
|
|
|
6282
6501
|
};
|
|
6283
6502
|
}
|
|
6284
6503
|
|
|
6285
|
-
function
|
|
6286
|
-
|
|
6504
|
+
function getDiskNumber(writer) {
|
|
6505
|
+
const { diskNumber = 0 } = writer;
|
|
6506
|
+
return diskNumber;
|
|
6507
|
+
}
|
|
6508
|
+
|
|
6509
|
+
function getDiskOffset(writer) {
|
|
6510
|
+
const { diskOffset = 0 } = writer;
|
|
6511
|
+
return diskOffset;
|
|
6512
|
+
}
|
|
6513
|
+
|
|
6514
|
+
function exceedsAvailableSize(writer, length) {
|
|
6515
|
+
const { availableSize = INFINITY_VALUE } = writer;
|
|
6516
|
+
return length > availableSize;
|
|
6517
|
+
}
|
|
6518
|
+
|
|
6519
|
+
function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
|
|
6520
|
+
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
6287
6521
|
}
|
|
6288
6522
|
|
|
6289
6523
|
async function writeData(writer, array) {
|
|
@@ -6360,9 +6594,6 @@
|
|
|
6360
6594
|
array.set(typedArray, offset);
|
|
6361
6595
|
}
|
|
6362
6596
|
|
|
6363
|
-
function getDataView(array) {
|
|
6364
|
-
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
6365
|
-
}
|
|
6366
6597
|
|
|
6367
6598
|
function getLength(...arrayLikes) {
|
|
6368
6599
|
let result = 0;
|
|
@@ -6620,9 +6851,7 @@
|
|
|
6620
6851
|
|
|
6621
6852
|
async getArrayBuffer(options) {
|
|
6622
6853
|
const array = await this.getUint8Array(options);
|
|
6623
|
-
return array.
|
|
6624
|
-
? array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength)
|
|
6625
|
-
: array.buffer;
|
|
6854
|
+
return toExactUint8Array(array).buffer;
|
|
6626
6855
|
}
|
|
6627
6856
|
|
|
6628
6857
|
replaceBlob(blob) {
|