@zip.js/zip.js 2.8.34 → 2.8.36
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 +5 -2
- package/dist/README.md +3 -1
- package/dist/zip-core.js +494 -221
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core.js +471 -221
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-native.js +498 -227
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +500 -229
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +496 -223
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +497 -224
- 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 +499 -226
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +498 -227
- package/index-native.min.js +1 -1
- package/index.cjs +500 -229
- package/index.d.cts +61 -0
- package/index.d.ts +61 -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 +230 -56
- package/lib/core/streams/aes-crypto-stream.js +1 -10
- package/lib/core/streams/codec-stream.js +37 -16
- 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-core.js
CHANGED
|
@@ -162,6 +162,7 @@
|
|
|
162
162
|
workerStarvationTimeout: 5000,
|
|
163
163
|
useWebWorkers: true,
|
|
164
164
|
useCompressionStream: true,
|
|
165
|
+
transferStreams: true,
|
|
165
166
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
166
167
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
167
168
|
};
|
|
@@ -176,13 +177,14 @@
|
|
|
176
177
|
"workerStarvationTimeout",
|
|
177
178
|
"useCompressionStream",
|
|
178
179
|
"useWebWorkers",
|
|
180
|
+
"transferStreams",
|
|
179
181
|
"CompressionStream",
|
|
180
182
|
"DecompressionStream",
|
|
181
183
|
"CompressionStreamZlib",
|
|
182
184
|
"DecompressionStreamZlib"
|
|
183
185
|
];
|
|
184
186
|
|
|
185
|
-
const config =
|
|
187
|
+
const config = { ...DEFAULT_CONFIGURATION };
|
|
186
188
|
|
|
187
189
|
function getConfiguration() {
|
|
188
190
|
return config;
|
|
@@ -201,6 +203,23 @@
|
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
205
|
|
|
206
|
+
function setDefaultConfiguration(configuration) {
|
|
207
|
+
for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
|
|
208
|
+
const propertyValue = configuration[propertyName];
|
|
209
|
+
if (propertyValue !== UNDEFINED_VALUE) {
|
|
210
|
+
DEFAULT_CONFIGURATION[propertyName] = propertyValue;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
configure(configuration);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function resetConfiguration() {
|
|
217
|
+
for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
|
|
218
|
+
delete config[propertyName];
|
|
219
|
+
}
|
|
220
|
+
Object.assign(config, DEFAULT_CONFIGURATION);
|
|
221
|
+
}
|
|
222
|
+
|
|
204
223
|
/*
|
|
205
224
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
206
225
|
|
|
@@ -383,6 +402,50 @@
|
|
|
383
402
|
}
|
|
384
403
|
}
|
|
385
404
|
|
|
405
|
+
/*
|
|
406
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
407
|
+
|
|
408
|
+
Redistribution and use in source and binary forms, with or without
|
|
409
|
+
modification, are permitted provided that the following conditions are met:
|
|
410
|
+
|
|
411
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
412
|
+
this list of conditions and the following disclaimer.
|
|
413
|
+
|
|
414
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
415
|
+
notice, this list of conditions and the following disclaimer in
|
|
416
|
+
the documentation and/or other materials provided with the distribution.
|
|
417
|
+
|
|
418
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
419
|
+
derived from this software without specific prior written permission.
|
|
420
|
+
|
|
421
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
422
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
423
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
424
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
425
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
426
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
427
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
428
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
429
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
430
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
431
|
+
*/
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
function concat(first, second) {
|
|
435
|
+
const result = new Uint8Array(first.length + second.length);
|
|
436
|
+
result.set(first);
|
|
437
|
+
result.set(second, first.length);
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function toExactUint8Array(array) {
|
|
442
|
+
return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function getDataView(array) {
|
|
446
|
+
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
447
|
+
}
|
|
448
|
+
|
|
386
449
|
// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
|
|
387
450
|
|
|
388
451
|
// deno-lint-ignore-file no-this-alias
|
|
@@ -1487,16 +1550,6 @@
|
|
|
1487
1550
|
}
|
|
1488
1551
|
}
|
|
1489
1552
|
|
|
1490
|
-
function concat(leftArray, rightArray) {
|
|
1491
|
-
let array = leftArray;
|
|
1492
|
-
if (leftArray.length + rightArray.length) {
|
|
1493
|
-
array = new Uint8Array(leftArray.length + rightArray.length);
|
|
1494
|
-
array.set(leftArray, 0);
|
|
1495
|
-
array.set(rightArray, leftArray.length);
|
|
1496
|
-
}
|
|
1497
|
-
return array;
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
1553
|
function expand(inputArray, length) {
|
|
1501
1554
|
if (length && length > inputArray.length) {
|
|
1502
1555
|
const array = inputArray;
|
|
@@ -1758,44 +1811,34 @@
|
|
|
1758
1811
|
constructor() {
|
|
1759
1812
|
// deno-lint-ignore prefer-const
|
|
1760
1813
|
let stream;
|
|
1761
|
-
let
|
|
1762
|
-
let
|
|
1814
|
+
let headerBytesLeft = GZIP_HEADER_LENGTH;
|
|
1815
|
+
let trailerCandidate = new Uint8Array(0);
|
|
1763
1816
|
super({
|
|
1764
1817
|
transform(chunk, controller) {
|
|
1765
|
-
if (
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
chunk = chunk.subarray(
|
|
1818
|
+
if (headerBytesLeft) {
|
|
1819
|
+
const droppedLength = Math.min(headerBytesLeft, chunk.length);
|
|
1820
|
+
headerBytesLeft -= droppedLength;
|
|
1821
|
+
chunk = chunk.subarray(droppedLength);
|
|
1769
1822
|
if (!chunk.length) {
|
|
1770
1823
|
return;
|
|
1771
1824
|
}
|
|
1772
1825
|
}
|
|
1773
|
-
const
|
|
1774
|
-
if (
|
|
1775
|
-
|
|
1776
|
-
pending.set(tail);
|
|
1777
|
-
pending.set(chunk, tail.length);
|
|
1778
|
-
tail = pending;
|
|
1826
|
+
const availableLength = trailerCandidate.length + chunk.length;
|
|
1827
|
+
if (availableLength <= GZIP_TRAILER_LENGTH) {
|
|
1828
|
+
trailerCandidate = concat(trailerCandidate, chunk);
|
|
1779
1829
|
return;
|
|
1780
1830
|
}
|
|
1781
|
-
const emitLength =
|
|
1782
|
-
const
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
const nextTail = new Uint8Array(GZIP_TRAILER_LENGTH);
|
|
1790
|
-
const tailRemaining = tail.length - fromTail;
|
|
1791
|
-
if (tailRemaining) {
|
|
1792
|
-
nextTail.set(tail.subarray(fromTail), 0);
|
|
1793
|
-
}
|
|
1794
|
-
nextTail.set(chunk.subarray(emitLength - fromTail), tailRemaining);
|
|
1795
|
-
tail = nextTail;
|
|
1831
|
+
const emitLength = availableLength - GZIP_TRAILER_LENGTH;
|
|
1832
|
+
const emittedFromTrailer = Math.min(emitLength, trailerCandidate.length);
|
|
1833
|
+
controller.enqueue(concat(
|
|
1834
|
+
trailerCandidate.subarray(0, emittedFromTrailer),
|
|
1835
|
+
chunk.subarray(0, emitLength - emittedFromTrailer)));
|
|
1836
|
+
trailerCandidate = concat(
|
|
1837
|
+
trailerCandidate.subarray(emittedFromTrailer),
|
|
1838
|
+
chunk.subarray(emitLength - emittedFromTrailer));
|
|
1796
1839
|
},
|
|
1797
1840
|
flush() {
|
|
1798
|
-
const dataView =
|
|
1841
|
+
const dataView = getDataView(trailerCandidate);
|
|
1799
1842
|
stream.signature = dataView.getUint32(0, true);
|
|
1800
1843
|
stream.uncompressedSize = dataView.getUint32(4, true);
|
|
1801
1844
|
}
|
|
@@ -1970,7 +2013,7 @@
|
|
|
1970
2013
|
*/
|
|
1971
2014
|
|
|
1972
2015
|
|
|
1973
|
-
const DEFAULT_CHUNK_SIZE
|
|
2016
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
1974
2017
|
const MESSAGE_EVENT_TYPE = "message";
|
|
1975
2018
|
const MESSAGE_START = "start";
|
|
1976
2019
|
const MESSAGE_PULL = "pull";
|
|
@@ -2038,33 +2081,54 @@
|
|
|
2038
2081
|
class ChunkStream extends TransformStream {
|
|
2039
2082
|
|
|
2040
2083
|
constructor(chunkSize) {
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2084
|
+
const pendingChunks = [];
|
|
2085
|
+
let pendingLength = 0;
|
|
2086
|
+
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2087
|
+
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2044
2088
|
}
|
|
2045
2089
|
super({
|
|
2046
|
-
transform,
|
|
2090
|
+
transform(chunk, controller) {
|
|
2091
|
+
pendingChunks.push(chunk);
|
|
2092
|
+
pendingLength += chunk.length;
|
|
2093
|
+
while (pendingLength > chunkSize) {
|
|
2094
|
+
controller.enqueue(shiftChunk());
|
|
2095
|
+
}
|
|
2096
|
+
},
|
|
2047
2097
|
flush(controller) {
|
|
2048
|
-
if (
|
|
2049
|
-
controller.enqueue(
|
|
2098
|
+
if (pendingLength) {
|
|
2099
|
+
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2050
2100
|
}
|
|
2051
2101
|
}
|
|
2052
2102
|
});
|
|
2053
2103
|
|
|
2054
|
-
function
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2104
|
+
function shiftChunk() {
|
|
2105
|
+
const result = new Uint8Array(chunkSize);
|
|
2106
|
+
let resultOffset = 0;
|
|
2107
|
+
while (resultOffset < chunkSize) {
|
|
2108
|
+
const firstChunk = pendingChunks[0];
|
|
2109
|
+
const remainingLength = chunkSize - resultOffset;
|
|
2110
|
+
if (firstChunk.length <= remainingLength) {
|
|
2111
|
+
result.set(firstChunk, resultOffset);
|
|
2112
|
+
resultOffset += firstChunk.length;
|
|
2113
|
+
pendingChunks.shift();
|
|
2114
|
+
} else {
|
|
2115
|
+
result.set(firstChunk.subarray(0, remainingLength), resultOffset);
|
|
2116
|
+
pendingChunks[0] = firstChunk.subarray(remainingLength);
|
|
2117
|
+
resultOffset += remainingLength;
|
|
2118
|
+
}
|
|
2061
2119
|
}
|
|
2120
|
+
pendingLength -= chunkSize;
|
|
2121
|
+
return result;
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
function concatChunks(chunks, length) {
|
|
2125
|
+
const result = new Uint8Array(length);
|
|
2062
2126
|
let offset = 0;
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
offset +=
|
|
2127
|
+
for (const chunk of chunks) {
|
|
2128
|
+
result.set(chunk, offset);
|
|
2129
|
+
offset += chunk.length;
|
|
2066
2130
|
}
|
|
2067
|
-
|
|
2131
|
+
return result;
|
|
2068
2132
|
}
|
|
2069
2133
|
}
|
|
2070
2134
|
}
|
|
@@ -2246,7 +2310,10 @@
|
|
|
2246
2310
|
}
|
|
2247
2311
|
}
|
|
2248
2312
|
codecStream = new CodecStream(options, config);
|
|
2249
|
-
await readable
|
|
2313
|
+
await readable
|
|
2314
|
+
.pipeThrough(codecStream)
|
|
2315
|
+
.pipeThrough(new ChunkStream(getChunkSize(config)))
|
|
2316
|
+
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2250
2317
|
const {
|
|
2251
2318
|
signature,
|
|
2252
2319
|
inputSize,
|
|
@@ -2445,7 +2512,7 @@
|
|
|
2445
2512
|
const { value, readable, writable } = message;
|
|
2446
2513
|
const transferables = [];
|
|
2447
2514
|
if (value) {
|
|
2448
|
-
message.value =
|
|
2515
|
+
message.value = toExactUint8Array(value);
|
|
2449
2516
|
transferables.push(message.value.buffer);
|
|
2450
2517
|
}
|
|
2451
2518
|
if (transferStreams && transferStreamsSupported) {
|
|
@@ -2569,8 +2636,8 @@
|
|
|
2569
2636
|
const { options, config } = workerOptions;
|
|
2570
2637
|
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
2571
2638
|
const { workerURI, maxWorkers } = config;
|
|
2572
|
-
workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
|
|
2573
|
-
const streamCopy = !compressed && !signed && !encrypted
|
|
2639
|
+
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
2640
|
+
const streamCopy = !compressed && !signed && !encrypted;
|
|
2574
2641
|
workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
2575
2642
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
2576
2643
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
@@ -2704,6 +2771,7 @@
|
|
|
2704
2771
|
|
|
2705
2772
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
2706
2773
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
2774
|
+
const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
|
|
2707
2775
|
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
2708
2776
|
const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
|
|
2709
2777
|
|
|
@@ -2714,13 +2782,16 @@
|
|
|
2714
2782
|
const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
|
|
2715
2783
|
const HTTP_HEADER_RANGE = "Range";
|
|
2716
2784
|
const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
|
2785
|
+
const HTTP_HEADER_ETAG = "Etag";
|
|
2786
|
+
const HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
|
|
2717
2787
|
const HTTP_METHOD_HEAD = "HEAD";
|
|
2718
2788
|
const HTTP_METHOD_GET = "GET";
|
|
2719
2789
|
const HTTP_RANGE_UNIT = "bytes";
|
|
2720
|
-
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
2721
2790
|
const DEFAULT_BUFFER_SIZE = 256 * 1024;
|
|
2791
|
+
const DEFAULT_MAXIMUM_RANGE_SIZE = 16 * 1024 * 1024;
|
|
2722
2792
|
|
|
2723
2793
|
const PROPERTY_NAME_WRITABLE = "writable";
|
|
2794
|
+
const DISK_BOUNDARY = Symbol();
|
|
2724
2795
|
|
|
2725
2796
|
class Stream {
|
|
2726
2797
|
|
|
@@ -2739,13 +2810,13 @@
|
|
|
2739
2810
|
return this.createReadable();
|
|
2740
2811
|
}
|
|
2741
2812
|
|
|
2742
|
-
createReadable({ offset = 0, size,
|
|
2813
|
+
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
2743
2814
|
const reader = this;
|
|
2744
2815
|
let chunkOffset = 0;
|
|
2745
2816
|
return new ReadableStream({
|
|
2746
2817
|
async pull(controller) {
|
|
2747
2818
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
2748
|
-
const data = await readUint8Array(reader, offset + chunkOffset, dataSize
|
|
2819
|
+
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
2749
2820
|
controller.enqueue(data);
|
|
2750
2821
|
if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
2751
2822
|
controller.close();
|
|
@@ -2767,7 +2838,7 @@
|
|
|
2767
2838
|
if (!writer.initialized) {
|
|
2768
2839
|
throw new Error(ERR_WRITER_NOT_INITIALIZED);
|
|
2769
2840
|
}
|
|
2770
|
-
return writer.writeUint8Array(chunk);
|
|
2841
|
+
return writer.writeUint8Array(toExactUint8Array(chunk));
|
|
2771
2842
|
}
|
|
2772
2843
|
});
|
|
2773
2844
|
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
@@ -2854,6 +2925,27 @@
|
|
|
2854
2925
|
}
|
|
2855
2926
|
}
|
|
2856
2927
|
|
|
2928
|
+
let blobSliceReliable;
|
|
2929
|
+
let blobSliceProbe;
|
|
2930
|
+
|
|
2931
|
+
function probeBlobSliceReliability() {
|
|
2932
|
+
blobSliceProbe = (async () => {
|
|
2933
|
+
try {
|
|
2934
|
+
const slicedBlob = new Blob([new Uint8Array(3)]).slice(1, 2);
|
|
2935
|
+
const streamReader = slicedBlob.stream().getReader();
|
|
2936
|
+
let streamedLength = 0;
|
|
2937
|
+
let result = await streamReader.read();
|
|
2938
|
+
while (!result.done) {
|
|
2939
|
+
streamedLength += result.value.length;
|
|
2940
|
+
result = await streamReader.read();
|
|
2941
|
+
}
|
|
2942
|
+
blobSliceReliable = streamedLength == 1;
|
|
2943
|
+
} catch {
|
|
2944
|
+
blobSliceReliable = false;
|
|
2945
|
+
}
|
|
2946
|
+
})();
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2857
2949
|
class BlobReader extends Reader {
|
|
2858
2950
|
|
|
2859
2951
|
constructor(blob) {
|
|
@@ -2862,14 +2954,32 @@
|
|
|
2862
2954
|
blob,
|
|
2863
2955
|
size: blob.size
|
|
2864
2956
|
});
|
|
2957
|
+
if (!blobSliceProbe) {
|
|
2958
|
+
probeBlobSliceReliability();
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
createReadable(options) {
|
|
2963
|
+
const reader = this;
|
|
2964
|
+
const { blob, size } = reader;
|
|
2965
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
2966
|
+
if (!offset && readSize >= size) {
|
|
2967
|
+
return blob.stream();
|
|
2968
|
+
}
|
|
2969
|
+
if (blobSliceReliable) {
|
|
2970
|
+
return blob.slice(offset, offset + readSize).stream();
|
|
2971
|
+
}
|
|
2972
|
+
return super.createReadable(options);
|
|
2865
2973
|
}
|
|
2866
2974
|
|
|
2867
2975
|
async readUint8Array(offset, length) {
|
|
2868
2976
|
const reader = this;
|
|
2869
2977
|
const offsetEnd = offset + length;
|
|
2870
|
-
const
|
|
2978
|
+
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
2979
|
+
const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
|
|
2871
2980
|
let arrayBuffer = await blob.arrayBuffer();
|
|
2872
|
-
|
|
2981
|
+
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
2982
|
+
if (sliceIgnoredByBuggyImplementation) {
|
|
2873
2983
|
arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
|
|
2874
2984
|
}
|
|
2875
2985
|
return new Uint8Array(arrayBuffer);
|
|
@@ -2950,6 +3060,18 @@
|
|
|
2950
3060
|
super.init();
|
|
2951
3061
|
}
|
|
2952
3062
|
|
|
3063
|
+
createReadable(options) {
|
|
3064
|
+
const reader = this;
|
|
3065
|
+
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
3066
|
+
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
3067
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3068
|
+
if (readSize > 0 && offset < size) {
|
|
3069
|
+
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
return super.createReadable(options);
|
|
3073
|
+
}
|
|
3074
|
+
|
|
2953
3075
|
readUint8Array(index, length) {
|
|
2954
3076
|
return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
|
|
2955
3077
|
}
|
|
@@ -2978,6 +3100,8 @@
|
|
|
2978
3100
|
useRangeHeader,
|
|
2979
3101
|
forceRangeRequests,
|
|
2980
3102
|
combineSizeEocd,
|
|
3103
|
+
checkResourceChanges = true,
|
|
3104
|
+
maximumRangeSize = DEFAULT_MAXIMUM_RANGE_SIZE,
|
|
2981
3105
|
fetch
|
|
2982
3106
|
} = options;
|
|
2983
3107
|
options = Object.assign({}, options);
|
|
@@ -2985,6 +3109,8 @@
|
|
|
2985
3109
|
delete options.useRangeHeader;
|
|
2986
3110
|
delete options.forceRangeRequests;
|
|
2987
3111
|
delete options.combineSizeEocd;
|
|
3112
|
+
delete options.checkResourceChanges;
|
|
3113
|
+
delete options.maximumRangeSize;
|
|
2988
3114
|
delete options.useXHR;
|
|
2989
3115
|
delete options.fetch;
|
|
2990
3116
|
Object.assign(httpReader, {
|
|
@@ -2994,6 +3120,8 @@
|
|
|
2994
3120
|
useRangeHeader,
|
|
2995
3121
|
forceRangeRequests,
|
|
2996
3122
|
combineSizeEocd,
|
|
3123
|
+
checkResourceChanges,
|
|
3124
|
+
maximumRangeSize,
|
|
2997
3125
|
fetch
|
|
2998
3126
|
});
|
|
2999
3127
|
}
|
|
@@ -3018,17 +3146,8 @@
|
|
|
3018
3146
|
httpReader.eocdCache = eocdCache;
|
|
3019
3147
|
}
|
|
3020
3148
|
}
|
|
3021
|
-
|
|
3022
|
-
const
|
|
3023
|
-
if (contentRangeHeader) {
|
|
3024
|
-
const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
|
|
3025
|
-
if (splitHeader.length) {
|
|
3026
|
-
const headerValue = splitHeader[1];
|
|
3027
|
-
if (headerValue && headerValue != "*") {
|
|
3028
|
-
contentSize = Number(headerValue);
|
|
3029
|
-
}
|
|
3030
|
-
}
|
|
3031
|
-
}
|
|
3149
|
+
setResourceValidators(httpReader, response);
|
|
3150
|
+
const contentSize = getContentRangeSize(response);
|
|
3032
3151
|
if (contentSize === UNDEFINED_VALUE) {
|
|
3033
3152
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
3034
3153
|
} else {
|
|
@@ -3069,6 +3188,8 @@
|
|
|
3069
3188
|
throw new Error(ERR_HTTP_RANGE);
|
|
3070
3189
|
}
|
|
3071
3190
|
}
|
|
3191
|
+
checkResourceValidators(httpReader, response);
|
|
3192
|
+
setResourceValidators(httpReader, response);
|
|
3072
3193
|
const data = new Uint8Array(await response.arrayBuffer());
|
|
3073
3194
|
if (data.length != length) {
|
|
3074
3195
|
throw new Error(ERR_HTTP_RANGE);
|
|
@@ -3080,7 +3201,114 @@
|
|
|
3080
3201
|
if (!data) {
|
|
3081
3202
|
await getRequestData(httpReader, options);
|
|
3082
3203
|
}
|
|
3083
|
-
return
|
|
3204
|
+
return httpReader.data.subarray(index, index + length);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
function createRangeReadable(httpReader, offset, size) {
|
|
3209
|
+
let bodyReader;
|
|
3210
|
+
let windowOffset = offset;
|
|
3211
|
+
let windowRemainingLength = 0;
|
|
3212
|
+
let remainingLength = size;
|
|
3213
|
+
return new ReadableStream({
|
|
3214
|
+
start() {
|
|
3215
|
+
return openWindow();
|
|
3216
|
+
},
|
|
3217
|
+
async pull(controller) {
|
|
3218
|
+
if (!bodyReader) {
|
|
3219
|
+
await openWindow();
|
|
3220
|
+
}
|
|
3221
|
+
const { value, done } = await bodyReader.read();
|
|
3222
|
+
if (done) {
|
|
3223
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
3224
|
+
}
|
|
3225
|
+
const chunk = value.length > windowRemainingLength ? value.subarray(0, windowRemainingLength) : value;
|
|
3226
|
+
windowRemainingLength -= chunk.length;
|
|
3227
|
+
remainingLength -= chunk.length;
|
|
3228
|
+
if (chunk.length) {
|
|
3229
|
+
controller.enqueue(chunk);
|
|
3230
|
+
}
|
|
3231
|
+
if (!windowRemainingLength) {
|
|
3232
|
+
await closeWindow();
|
|
3233
|
+
if (!remainingLength) {
|
|
3234
|
+
controller.close();
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
},
|
|
3238
|
+
cancel(reason) {
|
|
3239
|
+
return bodyReader && bodyReader.cancel(reason);
|
|
3240
|
+
}
|
|
3241
|
+
});
|
|
3242
|
+
|
|
3243
|
+
async function openWindow() {
|
|
3244
|
+
const windowLength = Math.min(httpReader.maximumRangeSize, remainingLength);
|
|
3245
|
+
const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, windowOffset, windowLength));
|
|
3246
|
+
if (response.status != 206) {
|
|
3247
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
3248
|
+
}
|
|
3249
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3250
|
+
if (contentRangeHeader) {
|
|
3251
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3252
|
+
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
3253
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
checkResourceValidators(httpReader, response);
|
|
3257
|
+
setResourceValidators(httpReader, response);
|
|
3258
|
+
windowOffset += windowLength;
|
|
3259
|
+
windowRemainingLength = windowLength;
|
|
3260
|
+
bodyReader = response.body.getReader();
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
async function closeWindow() {
|
|
3264
|
+
const currentBodyReader = bodyReader;
|
|
3265
|
+
bodyReader = UNDEFINED_VALUE;
|
|
3266
|
+
await currentBodyReader.cancel();
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
|
|
3270
|
+
function getContentRangeSize(response) {
|
|
3271
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3272
|
+
if (contentRangeHeader) {
|
|
3273
|
+
const headerValue = contentRangeHeader.trim().split(/\s*\/\s*/)[1];
|
|
3274
|
+
if (headerValue && headerValue != "*") {
|
|
3275
|
+
const contentSize = Number(headerValue);
|
|
3276
|
+
if (!Number.isNaN(contentSize)) {
|
|
3277
|
+
return contentSize;
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
|
|
3283
|
+
function getResourceValidators({ headers }) {
|
|
3284
|
+
return {
|
|
3285
|
+
etag: headers.get(HTTP_HEADER_ETAG) || UNDEFINED_VALUE,
|
|
3286
|
+
lastModified: headers.get(HTTP_HEADER_LAST_MODIFIED) || UNDEFINED_VALUE
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
function setResourceValidators(httpReader, response) {
|
|
3291
|
+
const { checkResourceChanges, resourceValidators } = httpReader;
|
|
3292
|
+
if (checkResourceChanges && !resourceValidators && response.status == 206) {
|
|
3293
|
+
httpReader.resourceValidators = getResourceValidators(response);
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3296
|
+
|
|
3297
|
+
function checkResourceValidators(httpReader, response) {
|
|
3298
|
+
const { checkResourceChanges, resourceValidators, size } = httpReader;
|
|
3299
|
+
if (checkResourceChanges) {
|
|
3300
|
+
const contentRangeSize = getContentRangeSize(response);
|
|
3301
|
+
if (contentRangeSize !== UNDEFINED_VALUE && size !== UNDEFINED_VALUE && contentRangeSize != size) {
|
|
3302
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
3303
|
+
}
|
|
3304
|
+
if (resourceValidators) {
|
|
3305
|
+
const validators = getResourceValidators(response);
|
|
3306
|
+
const changed = Object.entries(resourceValidators).some(([name, value]) =>
|
|
3307
|
+
value !== UNDEFINED_VALUE && validators[name] !== UNDEFINED_VALUE && value != validators[name]);
|
|
3308
|
+
if (changed) {
|
|
3309
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3084
3312
|
}
|
|
3085
3313
|
}
|
|
3086
3314
|
|
|
@@ -3191,6 +3419,10 @@
|
|
|
3191
3419
|
super.init();
|
|
3192
3420
|
}
|
|
3193
3421
|
|
|
3422
|
+
createReadable(options) {
|
|
3423
|
+
return this.reader.createReadable(options);
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3194
3426
|
readUint8Array(index, length) {
|
|
3195
3427
|
return this.reader.readUint8Array(index, length);
|
|
3196
3428
|
}
|
|
@@ -3271,25 +3503,26 @@
|
|
|
3271
3503
|
const reader = this;
|
|
3272
3504
|
const { readers } = reader;
|
|
3273
3505
|
reader.lastDiskNumber = 0;
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
if (indexDiskReader != readers.length - 1) {
|
|
3278
|
-
reader.lastDiskOffset += diskReader.size;
|
|
3279
|
-
}
|
|
3506
|
+
await Promise.all(readers.map(diskReader => initStream(diskReader)));
|
|
3507
|
+
reader.diskOffsets = readers.map(diskReader => {
|
|
3508
|
+
const diskOffset = reader.size;
|
|
3280
3509
|
reader.size += diskReader.size;
|
|
3281
|
-
|
|
3510
|
+
return diskOffset;
|
|
3511
|
+
});
|
|
3282
3512
|
super.init();
|
|
3283
3513
|
}
|
|
3284
3514
|
|
|
3285
|
-
|
|
3515
|
+
getDiskOffset(diskNumber) {
|
|
3516
|
+
const { diskOffsets, size } = this;
|
|
3517
|
+
const diskOffset = diskOffsets.at(diskNumber);
|
|
3518
|
+
return diskOffset === UNDEFINED_VALUE ? size : diskOffset;
|
|
3519
|
+
}
|
|
3520
|
+
|
|
3521
|
+
async readUint8Array(offset, length) {
|
|
3286
3522
|
const reader = this;
|
|
3287
3523
|
const { readers } = this;
|
|
3288
3524
|
let result;
|
|
3289
|
-
let currentDiskNumber =
|
|
3290
|
-
if (currentDiskNumber == -1) {
|
|
3291
|
-
currentDiskNumber = readers.length - 1;
|
|
3292
|
-
}
|
|
3525
|
+
let currentDiskNumber = 0;
|
|
3293
3526
|
let currentReaderOffset = offset;
|
|
3294
3527
|
while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
|
|
3295
3528
|
currentReaderOffset -= readers[currentDiskNumber].size;
|
|
@@ -3302,14 +3535,9 @@
|
|
|
3302
3535
|
result = await readUint8Array(currentReader, currentReaderOffset, length);
|
|
3303
3536
|
} else {
|
|
3304
3537
|
const chunkLength = currentReaderSize - currentReaderOffset;
|
|
3305
|
-
result = new Uint8Array(length);
|
|
3306
3538
|
const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength);
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
result.set(secondPart, chunkLength);
|
|
3310
|
-
if (firstPart.length + secondPart.length < length) {
|
|
3311
|
-
result = result.subarray(0, firstPart.length + secondPart.length);
|
|
3312
|
-
}
|
|
3539
|
+
const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength);
|
|
3540
|
+
result = concat(firstPart, secondPart);
|
|
3313
3541
|
}
|
|
3314
3542
|
} else {
|
|
3315
3543
|
result = EMPTY_UINT8_ARRAY;
|
|
@@ -3334,6 +3562,12 @@
|
|
|
3334
3562
|
let diskSourceWriter, diskWritable, diskWriter;
|
|
3335
3563
|
const writable = new WritableStream({
|
|
3336
3564
|
async write(chunk) {
|
|
3565
|
+
if (chunk === DISK_BOUNDARY) {
|
|
3566
|
+
if (diskWriter) {
|
|
3567
|
+
await endDisk();
|
|
3568
|
+
}
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3337
3571
|
const { availableSize } = writer;
|
|
3338
3572
|
if (!diskWriter) {
|
|
3339
3573
|
const { value, done } = await writerGenerator.next();
|
|
@@ -3353,11 +3587,7 @@
|
|
|
3353
3587
|
await this.write(chunk);
|
|
3354
3588
|
} else if (chunk.length >= availableSize) {
|
|
3355
3589
|
await writeChunk(chunk.subarray(0, availableSize));
|
|
3356
|
-
await
|
|
3357
|
-
writer.diskOffset += diskSourceWriter.size;
|
|
3358
|
-
writer.diskNumber++;
|
|
3359
|
-
diskWriter = null;
|
|
3360
|
-
writer.availableSize = writer.maxSize;
|
|
3590
|
+
await endDisk();
|
|
3361
3591
|
if (chunk.length > availableSize) {
|
|
3362
3592
|
await this.write(chunk.subarray(availableSize));
|
|
3363
3593
|
}
|
|
@@ -3368,7 +3598,7 @@
|
|
|
3368
3598
|
async close() {
|
|
3369
3599
|
if (diskWriter) {
|
|
3370
3600
|
await diskWriter.ready;
|
|
3371
|
-
await
|
|
3601
|
+
await closeDiskWriter();
|
|
3372
3602
|
}
|
|
3373
3603
|
},
|
|
3374
3604
|
async abort(reason) {
|
|
@@ -3393,10 +3623,28 @@
|
|
|
3393
3623
|
}
|
|
3394
3624
|
}
|
|
3395
3625
|
|
|
3396
|
-
async function
|
|
3626
|
+
async function endDisk() {
|
|
3627
|
+
await closeDiskWriter();
|
|
3628
|
+
writer.diskOffset += diskSourceWriter.size;
|
|
3629
|
+
writer.diskNumber++;
|
|
3630
|
+
diskWriter = null;
|
|
3631
|
+
writer.availableSize = writer.maxSize;
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
async function closeDiskWriter() {
|
|
3397
3635
|
await diskWriter.close();
|
|
3398
3636
|
}
|
|
3399
3637
|
}
|
|
3638
|
+
|
|
3639
|
+
async closeDisk() {
|
|
3640
|
+
const streamWriter = this.writable.getWriter();
|
|
3641
|
+
try {
|
|
3642
|
+
await streamWriter.ready;
|
|
3643
|
+
await streamWriter.write(DISK_BOUNDARY);
|
|
3644
|
+
} finally {
|
|
3645
|
+
streamWriter.releaseLock();
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3400
3648
|
}
|
|
3401
3649
|
|
|
3402
3650
|
class GenericReader {
|
|
@@ -3428,14 +3676,6 @@
|
|
|
3428
3676
|
if (writer.size === UNDEFINED_VALUE) {
|
|
3429
3677
|
writer.size = 0;
|
|
3430
3678
|
}
|
|
3431
|
-
if (!(writer instanceof SplitDataWriter)) {
|
|
3432
|
-
Object.assign(writer, {
|
|
3433
|
-
diskNumber: 0,
|
|
3434
|
-
diskOffset: 0,
|
|
3435
|
-
availableSize: INFINITY_VALUE,
|
|
3436
|
-
maxSize: INFINITY_VALUE
|
|
3437
|
-
});
|
|
3438
|
-
}
|
|
3439
3679
|
return writer;
|
|
3440
3680
|
}
|
|
3441
3681
|
}
|
|
@@ -3454,8 +3694,8 @@
|
|
|
3454
3694
|
}
|
|
3455
3695
|
}
|
|
3456
3696
|
|
|
3457
|
-
function readUint8Array(reader, offset, size
|
|
3458
|
-
return reader.readUint8Array(offset, size
|
|
3697
|
+
function readUint8Array(reader, offset, size) {
|
|
3698
|
+
return reader.readUint8Array(offset, size);
|
|
3459
3699
|
}
|
|
3460
3700
|
|
|
3461
3701
|
/*
|
|
@@ -3831,7 +4071,7 @@
|
|
|
3831
4071
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
3832
4072
|
if (!endOfDirectoryInfo) {
|
|
3833
4073
|
const signatureArray = await readUint8Array(reader, 0, 4);
|
|
3834
|
-
const signatureView = getDataView
|
|
4074
|
+
const signatureView = getDataView(signatureArray);
|
|
3835
4075
|
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
3836
4076
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
3837
4077
|
} else {
|
|
@@ -3841,7 +4081,7 @@
|
|
|
3841
4081
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
3842
4082
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
3843
4083
|
}
|
|
3844
|
-
const endOfDirectoryView = getDataView
|
|
4084
|
+
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
3845
4085
|
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
3846
4086
|
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
3847
4087
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
@@ -3857,17 +4097,21 @@
|
|
|
3857
4097
|
let prependedDataLength = 0;
|
|
3858
4098
|
let startOffset;
|
|
3859
4099
|
let zip64EndOfDirectory;
|
|
3860
|
-
|
|
4100
|
+
const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
|
|
4101
|
+
if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
|
|
4102
|
+
directoryDataOffset += getDiskOffset$1(reader, diskNumber);
|
|
4103
|
+
}
|
|
4104
|
+
if (requiresZip64) {
|
|
3861
4105
|
const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
|
|
3862
4106
|
await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
|
|
3863
4107
|
EMPTY_UINT8_ARRAY;
|
|
3864
|
-
const endOfDirectoryLocatorView = getDataView
|
|
4108
|
+
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
3865
4109
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
3866
4110
|
getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
|
|
3867
|
-
directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
|
|
3868
|
-
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
3869
|
-
let endOfDirectoryView = getDataView
|
|
3870
|
-
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
4111
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4112
|
+
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4113
|
+
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4114
|
+
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
3871
4115
|
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
3872
4116
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
3873
4117
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3875,8 +4119,8 @@
|
|
|
3875
4119
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3876
4120
|
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
3877
4121
|
}
|
|
3878
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
3879
|
-
endOfDirectoryView = getDataView
|
|
4122
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4123
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
3880
4124
|
}
|
|
3881
4125
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
3882
4126
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -3902,7 +4146,7 @@
|
|
|
3902
4146
|
} else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
3903
4147
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
3904
4148
|
}
|
|
3905
|
-
directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4149
|
+
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
3906
4150
|
}
|
|
3907
4151
|
}
|
|
3908
4152
|
const declaredDirectoryDataLength = directoryDataLength;
|
|
@@ -3919,19 +4163,19 @@
|
|
|
3919
4163
|
throw new Error(ERR_BAD_FORMAT);
|
|
3920
4164
|
}
|
|
3921
4165
|
let offset = 0;
|
|
3922
|
-
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3923
|
-
let directoryView = getDataView
|
|
4166
|
+
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4167
|
+
let directoryView = getDataView(directoryArray);
|
|
3924
4168
|
if (directoryDataLength) {
|
|
3925
4169
|
if (directoryArray.length < 4) {
|
|
3926
4170
|
throw new Error(ERR_BAD_FORMAT);
|
|
3927
4171
|
}
|
|
3928
|
-
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength
|
|
4172
|
+
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
3929
4173
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
3930
4174
|
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3931
4175
|
let reconcile = !storedPointsAtDirectory;
|
|
3932
4176
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
3933
|
-
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4
|
|
3934
|
-
reconcile = getUint32(getDataView
|
|
4177
|
+
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4178
|
+
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3935
4179
|
}
|
|
3936
4180
|
if (reconcile) {
|
|
3937
4181
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3939,16 +4183,16 @@
|
|
|
3939
4183
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3940
4184
|
prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
|
|
3941
4185
|
}
|
|
3942
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3943
|
-
directoryView = getDataView
|
|
4186
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4187
|
+
directoryView = getDataView(directoryArray);
|
|
3944
4188
|
}
|
|
3945
4189
|
}
|
|
3946
4190
|
}
|
|
3947
|
-
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset
|
|
4191
|
+
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
3948
4192
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
3949
4193
|
directoryDataLength = expectedDirectoryDataLength;
|
|
3950
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3951
|
-
directoryView = getDataView
|
|
4194
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4195
|
+
directoryView = getDataView(directoryArray);
|
|
3952
4196
|
}
|
|
3953
4197
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
3954
4198
|
throw new Error(ERR_BAD_FORMAT);
|
|
@@ -4021,7 +4265,7 @@
|
|
|
4021
4265
|
});
|
|
4022
4266
|
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
|
|
4023
4267
|
fileEntry.offset += prependedDataLength;
|
|
4024
|
-
startOffset = Math.min(fileEntry.offset, startOffset);
|
|
4268
|
+
startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
|
|
4025
4269
|
if (checkAmbiguity) {
|
|
4026
4270
|
if (filenames.has(fileEntry.filename)) {
|
|
4027
4271
|
duplicateFilename = true;
|
|
@@ -4175,8 +4419,9 @@
|
|
|
4175
4419
|
dataDescriptor
|
|
4176
4420
|
} = bitFlag;
|
|
4177
4421
|
const localDirectory = fileEntry.localDirectory = {};
|
|
4178
|
-
const
|
|
4179
|
-
const
|
|
4422
|
+
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
4423
|
+
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
4424
|
+
const dataView = getDataView(dataArray);
|
|
4180
4425
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
4181
4426
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
4182
4427
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
@@ -4201,12 +4446,12 @@
|
|
|
4201
4446
|
const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
|
|
4202
4447
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
4203
4448
|
if (checkAmbiguity && (filenameLength || extraFieldLength)) {
|
|
4204
|
-
const trailingDataArray = await readUint8Array(reader,
|
|
4449
|
+
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
4205
4450
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
4206
4451
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
4207
4452
|
} else {
|
|
4208
4453
|
localDirectory.rawExtraField = extraFieldLength ?
|
|
4209
|
-
await readUint8Array(reader,
|
|
4454
|
+
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
4210
4455
|
EMPTY_UINT8_ARRAY;
|
|
4211
4456
|
}
|
|
4212
4457
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
@@ -4232,9 +4477,9 @@
|
|
|
4232
4477
|
throw new Error(ERR_ENCRYPTED);
|
|
4233
4478
|
}
|
|
4234
4479
|
}
|
|
4235
|
-
const dataOffset =
|
|
4480
|
+
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4236
4481
|
const size = compressedSize;
|
|
4237
|
-
const readable = reader.createReadable({ offset: dataOffset, size
|
|
4482
|
+
const readable = reader.createReadable({ offset: dataOffset, size });
|
|
4238
4483
|
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
4239
4484
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
4240
4485
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -4275,8 +4520,7 @@
|
|
|
4275
4520
|
reader,
|
|
4276
4521
|
fileEntry,
|
|
4277
4522
|
index,
|
|
4278
|
-
offset,
|
|
4279
|
-
diskNumberStart,
|
|
4523
|
+
offset: localHeaderOffset,
|
|
4280
4524
|
signature,
|
|
4281
4525
|
compressedSize,
|
|
4282
4526
|
uncompressedSize,
|
|
@@ -4340,7 +4584,7 @@
|
|
|
4340
4584
|
function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
|
|
4341
4585
|
const { rawExtraField } = directory;
|
|
4342
4586
|
const extraField = directory.extraField = new Map();
|
|
4343
|
-
const rawExtraFieldView = getDataView
|
|
4587
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
4344
4588
|
let offsetExtraField = 0;
|
|
4345
4589
|
try {
|
|
4346
4590
|
while (offsetExtraField < rawExtraField.length) {
|
|
@@ -4412,7 +4656,7 @@
|
|
|
4412
4656
|
|
|
4413
4657
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
4414
4658
|
directory.zip64 = true;
|
|
4415
|
-
const extraFieldView = getDataView
|
|
4659
|
+
const extraFieldView = getDataView(extraFieldZip64.data);
|
|
4416
4660
|
const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
|
|
4417
4661
|
const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
|
|
4418
4662
|
if (extraFieldZip64.data.length < requiredLength) {
|
|
@@ -4431,10 +4675,10 @@
|
|
|
4431
4675
|
extraFieldUnicode.valid = false;
|
|
4432
4676
|
return;
|
|
4433
4677
|
}
|
|
4434
|
-
const extraFieldView = getDataView
|
|
4678
|
+
const extraFieldView = getDataView(extraFieldUnicode.data);
|
|
4435
4679
|
const crc32 = new Crc32();
|
|
4436
4680
|
crc32.append(fileEntry[rawPropertyName]);
|
|
4437
|
-
const dataViewSignature = getDataView
|
|
4681
|
+
const dataViewSignature = getDataView(new Uint8Array(4));
|
|
4438
4682
|
dataViewSignature.setUint32(0, crc32.get(), true);
|
|
4439
4683
|
const signature = getUint32(extraFieldView, 1);
|
|
4440
4684
|
Object.assign(extraFieldUnicode, {
|
|
@@ -4449,7 +4693,7 @@
|
|
|
4449
4693
|
}
|
|
4450
4694
|
|
|
4451
4695
|
function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
|
|
4452
|
-
const extraFieldView = getDataView
|
|
4696
|
+
const extraFieldView = getDataView(extraFieldAES.data);
|
|
4453
4697
|
const strength = getUint8(extraFieldView, 4);
|
|
4454
4698
|
Object.assign(extraFieldAES, {
|
|
4455
4699
|
vendorVersion: getUint8(extraFieldView, 0),
|
|
@@ -4462,7 +4706,7 @@
|
|
|
4462
4706
|
}
|
|
4463
4707
|
|
|
4464
4708
|
function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
4465
|
-
const extraFieldView = getDataView
|
|
4709
|
+
const extraFieldView = getDataView(extraFieldNTFS.data);
|
|
4466
4710
|
let offsetExtraField = 4;
|
|
4467
4711
|
let tag1Data;
|
|
4468
4712
|
try {
|
|
@@ -4479,7 +4723,7 @@
|
|
|
4479
4723
|
}
|
|
4480
4724
|
try {
|
|
4481
4725
|
if (tag1Data && tag1Data.length == 24) {
|
|
4482
|
-
const tag1View = getDataView
|
|
4726
|
+
const tag1View = getDataView(tag1Data);
|
|
4483
4727
|
const rawLastModDate = tag1View.getBigUint64(0, true);
|
|
4484
4728
|
const rawLastAccessDate = tag1View.getBigUint64(8, true);
|
|
4485
4729
|
const rawCreationDate = tag1View.getBigUint64(16, true);
|
|
@@ -4502,7 +4746,7 @@
|
|
|
4502
4746
|
|
|
4503
4747
|
function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
4504
4748
|
try {
|
|
4505
|
-
const view = getDataView
|
|
4749
|
+
const view = getDataView(extraField.data);
|
|
4506
4750
|
let uid, gid;
|
|
4507
4751
|
if (isInfoZip) {
|
|
4508
4752
|
let offset = 0;
|
|
@@ -4540,7 +4784,7 @@
|
|
|
4540
4784
|
if (!extraFieldExtendedTimestamp.data.length) {
|
|
4541
4785
|
return;
|
|
4542
4786
|
}
|
|
4543
|
-
const extraFieldView = getDataView
|
|
4787
|
+
const extraFieldView = getDataView(extraFieldExtendedTimestamp.data);
|
|
4544
4788
|
const flags = getUint8(extraFieldView, 0);
|
|
4545
4789
|
const timeProperties = [];
|
|
4546
4790
|
const timeRawProperties = [];
|
|
@@ -4578,7 +4822,6 @@
|
|
|
4578
4822
|
fileEntry,
|
|
4579
4823
|
index,
|
|
4580
4824
|
offset,
|
|
4581
|
-
diskNumberStart,
|
|
4582
4825
|
signature,
|
|
4583
4826
|
compressedSize,
|
|
4584
4827
|
uncompressedSize,
|
|
@@ -4587,12 +4830,6 @@
|
|
|
4587
4830
|
extraFieldZip64,
|
|
4588
4831
|
readRanges
|
|
4589
4832
|
}) {
|
|
4590
|
-
let diskOffset = 0;
|
|
4591
|
-
if (diskNumberStart && reader.readers) {
|
|
4592
|
-
for (let indexReader = 0; indexReader < Math.min(diskNumberStart, reader.readers.length); indexReader++) {
|
|
4593
|
-
diskOffset += reader.readers[indexReader].size;
|
|
4594
|
-
}
|
|
4595
|
-
}
|
|
4596
4833
|
let dataDescriptorLength = 0;
|
|
4597
4834
|
if (dataDescriptor) {
|
|
4598
4835
|
if (extraFieldZip64) {
|
|
@@ -4602,19 +4839,19 @@
|
|
|
4602
4839
|
}
|
|
4603
4840
|
}
|
|
4604
4841
|
if (dataDescriptorLength) {
|
|
4605
|
-
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH
|
|
4842
|
+
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
4606
4843
|
const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
4607
|
-
getUint32(getDataView
|
|
4844
|
+
getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
4608
4845
|
if (dataDescriptorSignature) {
|
|
4609
|
-
const readSignature = getUint32(getDataView
|
|
4846
|
+
const readSignature = getUint32(getDataView(dataDescriptorArray), 4);
|
|
4610
4847
|
let readCompressedSize;
|
|
4611
4848
|
let readUncompressedSize;
|
|
4612
4849
|
if (extraFieldZip64) {
|
|
4613
|
-
readCompressedSize = getBigUint64(getDataView
|
|
4614
|
-
readUncompressedSize = getBigUint64(getDataView
|
|
4850
|
+
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
4851
|
+
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
4615
4852
|
} else {
|
|
4616
|
-
readCompressedSize = getUint32(getDataView
|
|
4617
|
-
readUncompressedSize = getUint32(getDataView
|
|
4853
|
+
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
4854
|
+
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
4618
4855
|
}
|
|
4619
4856
|
const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
|
|
4620
4857
|
if (matchSignature &&
|
|
@@ -4625,8 +4862,8 @@
|
|
|
4625
4862
|
}
|
|
4626
4863
|
}
|
|
4627
4864
|
const range = {
|
|
4628
|
-
start:
|
|
4629
|
-
end:
|
|
4865
|
+
start: offset,
|
|
4866
|
+
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
4630
4867
|
fileEntry
|
|
4631
4868
|
};
|
|
4632
4869
|
for (const [otherIndex, otherRange] of readRanges) {
|
|
@@ -4639,6 +4876,10 @@
|
|
|
4639
4876
|
readRanges.set(index, range);
|
|
4640
4877
|
}
|
|
4641
4878
|
|
|
4879
|
+
function getDiskOffset$1(reader, diskNumber) {
|
|
4880
|
+
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
4881
|
+
}
|
|
4882
|
+
|
|
4642
4883
|
function getStrictness(strictness, checkAmbiguity) {
|
|
4643
4884
|
if (strictness === UNDEFINED_VALUE) {
|
|
4644
4885
|
return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
|
|
@@ -4722,7 +4963,7 @@
|
|
|
4722
4963
|
async function* scanEndOfCentralDirectory(reader, scanLength) {
|
|
4723
4964
|
const scanOffset = reader.size - scanLength;
|
|
4724
4965
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
4725
|
-
const scanView = getDataView
|
|
4966
|
+
const scanView = getDataView(scanArray);
|
|
4726
4967
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
4727
4968
|
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4728
4969
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
@@ -4745,7 +4986,8 @@
|
|
|
4745
4986
|
if (!filesLength && !directoryDataLength) {
|
|
4746
4987
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
4747
4988
|
}
|
|
4748
|
-
|
|
4989
|
+
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
4990
|
+
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
4749
4991
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4750
4992
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
4751
4993
|
}
|
|
@@ -4763,7 +5005,7 @@
|
|
|
4763
5005
|
if (remoteProbeBudget.count > 0) {
|
|
4764
5006
|
remoteProbeBudget.count--;
|
|
4765
5007
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
4766
|
-
return getUint32(getDataView
|
|
5008
|
+
return getUint32(getDataView(signatureArray), 0);
|
|
4767
5009
|
}
|
|
4768
5010
|
return UNDEFINED_VALUE;
|
|
4769
5011
|
}
|
|
@@ -4828,9 +5070,27 @@
|
|
|
4828
5070
|
return Number(view.getBigUint64(offset, true));
|
|
4829
5071
|
}
|
|
4830
5072
|
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
5073
|
+
var zipReader = /*#__PURE__*/Object.freeze({
|
|
5074
|
+
__proto__: null,
|
|
5075
|
+
ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
|
|
5076
|
+
ERR_BAD_FORMAT: ERR_BAD_FORMAT,
|
|
5077
|
+
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
5078
|
+
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
5079
|
+
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5080
|
+
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5081
|
+
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
5082
|
+
ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
|
|
5083
|
+
ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
|
|
5084
|
+
ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
|
|
5085
|
+
ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
|
|
5086
|
+
ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
|
|
5087
|
+
ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
|
|
5088
|
+
ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
|
|
5089
|
+
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
5090
|
+
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
5091
|
+
ZipReader: ZipReader,
|
|
5092
|
+
ZipReaderStream: ZipReaderStream
|
|
5093
|
+
});
|
|
4834
5094
|
|
|
4835
5095
|
/*
|
|
4836
5096
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -4895,9 +5155,10 @@
|
|
|
4895
5155
|
|
|
4896
5156
|
constructor(writer, options = {}) {
|
|
4897
5157
|
writer = new GenericWriter(writer);
|
|
5158
|
+
const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
|
|
4898
5159
|
const addSplitZipSignature =
|
|
4899
|
-
|
|
4900
|
-
|
|
5160
|
+
availableSize > 0 && availableSize !== INFINITY_VALUE &&
|
|
5161
|
+
maxSize > 0 && maxSize !== INFINITY_VALUE;
|
|
4901
5162
|
Object.assign(this, {
|
|
4902
5163
|
writer,
|
|
4903
5164
|
addSplitZipSignature,
|
|
@@ -4919,9 +5180,10 @@
|
|
|
4919
5180
|
}
|
|
4920
5181
|
reader = new GenericReader(reader);
|
|
4921
5182
|
await initStream(reader);
|
|
4922
|
-
const
|
|
4923
|
-
const
|
|
4924
|
-
await zipReader.
|
|
5183
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5184
|
+
const zipReader$1 = new ZipReader(reader.readable);
|
|
5185
|
+
const entries = await zipReader$1.getEntries();
|
|
5186
|
+
await zipReader$1.close();
|
|
4925
5187
|
await initStream(this.writer);
|
|
4926
5188
|
await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
|
|
4927
5189
|
this.writer.size = this.offset = reader.size;
|
|
@@ -4937,8 +5199,6 @@
|
|
|
4937
5199
|
encrypted,
|
|
4938
5200
|
uncompressedSize,
|
|
4939
5201
|
compressedSize,
|
|
4940
|
-
diskOffset,
|
|
4941
|
-
diskNumber,
|
|
4942
5202
|
zip64
|
|
4943
5203
|
} = entry;
|
|
4944
5204
|
let {
|
|
@@ -4986,8 +5246,9 @@
|
|
|
4986
5246
|
Object.assign(entry, {
|
|
4987
5247
|
zip64UncompressedSize,
|
|
4988
5248
|
zip64CompressedSize,
|
|
4989
|
-
zip64Offset: zip64 &&
|
|
4990
|
-
|
|
5249
|
+
zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
|
|
5250
|
+
diskNumberStart: 0,
|
|
5251
|
+
zip64DiskNumberStart: false,
|
|
4991
5252
|
rawExtraFieldZip64,
|
|
4992
5253
|
rawExtraFieldAES,
|
|
4993
5254
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -5154,7 +5415,8 @@
|
|
|
5154
5415
|
try {
|
|
5155
5416
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
5156
5417
|
({ reader } = sizesInfo);
|
|
5157
|
-
const
|
|
5418
|
+
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
5419
|
+
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
5158
5420
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
5159
5421
|
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
5160
5422
|
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
@@ -5331,7 +5593,7 @@
|
|
|
5331
5593
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
5332
5594
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
5333
5595
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5334
|
-
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS
|
|
5596
|
+
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
5335
5597
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
5336
5598
|
const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
5337
5599
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
@@ -5529,7 +5791,7 @@
|
|
|
5529
5791
|
await requestLockWriter();
|
|
5530
5792
|
}
|
|
5531
5793
|
await initStream(fileWriter);
|
|
5532
|
-
const
|
|
5794
|
+
const diskOffset = getDiskOffset(writer);
|
|
5533
5795
|
if (zipWriter.addSplitZipSignature) {
|
|
5534
5796
|
delete zipWriter.addSplitZipSignature;
|
|
5535
5797
|
const signatureArray = new Uint8Array(4);
|
|
@@ -5546,7 +5808,7 @@
|
|
|
5546
5808
|
await lockPreviousFileEntry;
|
|
5547
5809
|
await skipDiskIfNeeded();
|
|
5548
5810
|
}
|
|
5549
|
-
const diskNumberStart = writer
|
|
5811
|
+
const diskNumberStart = getDiskNumber(writer);
|
|
5550
5812
|
const entryOffset = getSegmentOffset(zipWriter, writer);
|
|
5551
5813
|
fileEntry.diskNumberStart = diskNumberStart;
|
|
5552
5814
|
if (!bufferedWrite) {
|
|
@@ -5566,11 +5828,11 @@
|
|
|
5566
5828
|
writingBufferedEntryData = true;
|
|
5567
5829
|
writerSizeBeforeEntry = writer.size;
|
|
5568
5830
|
await skipDiskIfNeeded();
|
|
5569
|
-
fileEntry.diskNumberStart = writer
|
|
5831
|
+
fileEntry.diskNumberStart = getDiskNumber(writer);
|
|
5570
5832
|
fileEntry.offset = getSegmentOffset(zipWriter, writer);
|
|
5571
5833
|
if (usdz) {
|
|
5572
5834
|
const previousMetadataSize = entryInfo.metadataSize;
|
|
5573
|
-
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer
|
|
5835
|
+
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
|
|
5574
5836
|
fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
|
|
5575
5837
|
}
|
|
5576
5838
|
updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
|
|
@@ -5635,9 +5897,8 @@
|
|
|
5635
5897
|
}
|
|
5636
5898
|
|
|
5637
5899
|
async function skipDiskIfNeeded() {
|
|
5638
|
-
if (getLength(headerInfo.localHeaderArray)
|
|
5639
|
-
writer.
|
|
5640
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
5900
|
+
if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
|
|
5901
|
+
await writer.closeDisk();
|
|
5641
5902
|
}
|
|
5642
5903
|
}
|
|
5643
5904
|
}
|
|
@@ -5748,7 +6009,7 @@
|
|
|
5748
6009
|
}
|
|
5749
6010
|
const { writable } = writer;
|
|
5750
6011
|
if (reader) {
|
|
5751
|
-
const readable = reader.createReadable ? reader.createReadable(
|
|
6012
|
+
const readable = reader.createReadable ? reader.createReadable() : reader.readable;
|
|
5752
6013
|
const size = reader.size;
|
|
5753
6014
|
const workerOptions = {
|
|
5754
6015
|
options: {
|
|
@@ -6180,8 +6441,8 @@
|
|
|
6180
6441
|
|
|
6181
6442
|
async function closeFile(zipWriter, comment, options) {
|
|
6182
6443
|
const directoryDataLength = createDirectoryRecords(zipWriter.files);
|
|
6183
|
-
const
|
|
6184
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, {
|
|
6444
|
+
const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6445
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
|
|
6185
6446
|
}
|
|
6186
6447
|
|
|
6187
6448
|
function createDirectoryRecords(files) {
|
|
@@ -6263,8 +6524,8 @@
|
|
|
6263
6524
|
await initStream(writer);
|
|
6264
6525
|
let offset = 0;
|
|
6265
6526
|
let directoryDiskOffset = 0;
|
|
6266
|
-
let
|
|
6267
|
-
let
|
|
6527
|
+
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
6528
|
+
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
6268
6529
|
for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
|
|
6269
6530
|
const {
|
|
6270
6531
|
offset: fileEntryOffset,
|
|
@@ -6291,15 +6552,14 @@
|
|
|
6291
6552
|
} = fileEntry;
|
|
6292
6553
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6293
6554
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
6294
|
-
if (offset + directoryRecordLength - directoryDiskOffset
|
|
6555
|
+
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
6295
6556
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
6296
6557
|
directoryDiskOffset = offset;
|
|
6297
|
-
writer.
|
|
6298
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
6558
|
+
await writer.closeDisk();
|
|
6299
6559
|
}
|
|
6300
6560
|
if (indexFileEntry == 0) {
|
|
6301
|
-
|
|
6302
|
-
|
|
6561
|
+
directoryStartDiskNumber = getDiskNumber(writer);
|
|
6562
|
+
directoryStartDiskOffset = getDiskOffset(writer);
|
|
6303
6563
|
}
|
|
6304
6564
|
if (!zip64UncompressedSize) {
|
|
6305
6565
|
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
|
|
@@ -6339,18 +6599,18 @@
|
|
|
6339
6599
|
}
|
|
6340
6600
|
}
|
|
6341
6601
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
6342
|
-
return {
|
|
6602
|
+
return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
|
|
6343
6603
|
}
|
|
6344
6604
|
|
|
6345
6605
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
6346
6606
|
const { writer } = zipWriter;
|
|
6347
|
-
const {
|
|
6607
|
+
const { directoryStart } = cdInfo;
|
|
6348
6608
|
let { directoryDataLength } = cdInfo;
|
|
6349
6609
|
let filesLength = zipWriter.files.size;
|
|
6350
|
-
let diskNumber =
|
|
6351
|
-
let directoryOffset =
|
|
6352
|
-
let lastDiskNumber = writer
|
|
6353
|
-
if (writer
|
|
6610
|
+
let diskNumber = directoryStart.diskNumber;
|
|
6611
|
+
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
6612
|
+
let lastDiskNumber = getDiskNumber(writer);
|
|
6613
|
+
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
6354
6614
|
lastDiskNumber++;
|
|
6355
6615
|
}
|
|
6356
6616
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
@@ -6366,11 +6626,10 @@
|
|
|
6366
6626
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6367
6627
|
}
|
|
6368
6628
|
const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
6369
|
-
if (getLength(endOfdirectoryRecord.array) + commentLength
|
|
6370
|
-
writer.
|
|
6371
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
6629
|
+
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
6630
|
+
await writer.closeDisk();
|
|
6372
6631
|
}
|
|
6373
|
-
lastDiskNumber = writer
|
|
6632
|
+
lastDiskNumber = getDiskNumber(writer);
|
|
6374
6633
|
if (zip64) {
|
|
6375
6634
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
6376
6635
|
endOfdirectoryRecord.uint64(44);
|
|
@@ -6384,7 +6643,7 @@
|
|
|
6384
6643
|
endOfdirectoryRecord.uint64(directoryOffset);
|
|
6385
6644
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
6386
6645
|
endOfdirectoryRecord.uint32(lastDiskNumber);
|
|
6387
|
-
endOfdirectoryRecord.uint64(BigInt(zipWriter
|
|
6646
|
+
endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
|
|
6388
6647
|
endOfdirectoryRecord.uint32(lastDiskNumber + 1);
|
|
6389
6648
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
6390
6649
|
if (supportZip64SplitFile) {
|
|
@@ -6424,8 +6683,23 @@
|
|
|
6424
6683
|
};
|
|
6425
6684
|
}
|
|
6426
6685
|
|
|
6427
|
-
function
|
|
6428
|
-
|
|
6686
|
+
function getDiskNumber(writer) {
|
|
6687
|
+
const { diskNumber = 0 } = writer;
|
|
6688
|
+
return diskNumber;
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6691
|
+
function getDiskOffset(writer) {
|
|
6692
|
+
const { diskOffset = 0 } = writer;
|
|
6693
|
+
return diskOffset;
|
|
6694
|
+
}
|
|
6695
|
+
|
|
6696
|
+
function exceedsAvailableSize(writer, length) {
|
|
6697
|
+
const { availableSize = INFINITY_VALUE } = writer;
|
|
6698
|
+
return length > availableSize;
|
|
6699
|
+
}
|
|
6700
|
+
|
|
6701
|
+
function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
|
|
6702
|
+
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
6429
6703
|
}
|
|
6430
6704
|
|
|
6431
6705
|
async function writeData(writer, array) {
|
|
@@ -6502,9 +6776,6 @@
|
|
|
6502
6776
|
array.set(typedArray, offset);
|
|
6503
6777
|
}
|
|
6504
6778
|
|
|
6505
|
-
function getDataView(array) {
|
|
6506
|
-
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
6507
|
-
}
|
|
6508
6779
|
|
|
6509
6780
|
function getLength(...arrayLikes) {
|
|
6510
6781
|
let result = 0;
|
|
@@ -7045,7 +7316,7 @@
|
|
|
7045
7316
|
|
|
7046
7317
|
|
|
7047
7318
|
try {
|
|
7048
|
-
|
|
7319
|
+
setDefaultConfiguration({ baseURI: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('zip-core.js', document.baseURI).href)) });
|
|
7049
7320
|
} catch {
|
|
7050
7321
|
// ignored
|
|
7051
7322
|
}
|
|
@@ -7063,6 +7334,7 @@
|
|
|
7063
7334
|
exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
|
|
7064
7335
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
7065
7336
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
7337
|
+
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
7066
7338
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
7067
7339
|
exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
|
|
7068
7340
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
@@ -7104,6 +7376,7 @@
|
|
|
7104
7376
|
exports.createOPFSTempStream = createOPFSTempStream;
|
|
7105
7377
|
exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
|
|
7106
7378
|
exports.getMimeType = getMimeType;
|
|
7379
|
+
exports.resetConfiguration = resetConfiguration;
|
|
7107
7380
|
exports.terminateWorkers = terminateWorkers;
|
|
7108
7381
|
|
|
7109
7382
|
}));
|