@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-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,16 @@
|
|
|
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;
|
|
271
|
+
const DEFAULT_MAXIMUM_RANGE_SIZE = 16 * 1024 * 1024;
|
|
224
272
|
|
|
225
273
|
const PROPERTY_NAME_WRITABLE = "writable";
|
|
274
|
+
const DISK_BOUNDARY = Symbol();
|
|
226
275
|
|
|
227
276
|
class Stream {
|
|
228
277
|
|
|
@@ -241,13 +290,13 @@
|
|
|
241
290
|
return this.createReadable();
|
|
242
291
|
}
|
|
243
292
|
|
|
244
|
-
createReadable({ offset = 0, size,
|
|
293
|
+
createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
|
|
245
294
|
const reader = this;
|
|
246
295
|
let chunkOffset = 0;
|
|
247
296
|
return new ReadableStream({
|
|
248
297
|
async pull(controller) {
|
|
249
298
|
const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
|
|
250
|
-
const data = await readUint8Array(reader, offset + chunkOffset, dataSize
|
|
299
|
+
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
251
300
|
controller.enqueue(data);
|
|
252
301
|
if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
|
|
253
302
|
controller.close();
|
|
@@ -269,7 +318,7 @@
|
|
|
269
318
|
if (!writer.initialized) {
|
|
270
319
|
throw new Error(ERR_WRITER_NOT_INITIALIZED);
|
|
271
320
|
}
|
|
272
|
-
return writer.writeUint8Array(chunk);
|
|
321
|
+
return writer.writeUint8Array(toExactUint8Array(chunk));
|
|
273
322
|
}
|
|
274
323
|
});
|
|
275
324
|
Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
|
|
@@ -356,6 +405,27 @@
|
|
|
356
405
|
}
|
|
357
406
|
}
|
|
358
407
|
|
|
408
|
+
let blobSliceReliable;
|
|
409
|
+
let blobSliceProbe;
|
|
410
|
+
|
|
411
|
+
function probeBlobSliceReliability() {
|
|
412
|
+
blobSliceProbe = (async () => {
|
|
413
|
+
try {
|
|
414
|
+
const slicedBlob = new Blob([new Uint8Array(3)]).slice(1, 2);
|
|
415
|
+
const streamReader = slicedBlob.stream().getReader();
|
|
416
|
+
let streamedLength = 0;
|
|
417
|
+
let result = await streamReader.read();
|
|
418
|
+
while (!result.done) {
|
|
419
|
+
streamedLength += result.value.length;
|
|
420
|
+
result = await streamReader.read();
|
|
421
|
+
}
|
|
422
|
+
blobSliceReliable = streamedLength == 1;
|
|
423
|
+
} catch {
|
|
424
|
+
blobSliceReliable = false;
|
|
425
|
+
}
|
|
426
|
+
})();
|
|
427
|
+
}
|
|
428
|
+
|
|
359
429
|
class BlobReader extends Reader {
|
|
360
430
|
|
|
361
431
|
constructor(blob) {
|
|
@@ -364,14 +434,32 @@
|
|
|
364
434
|
blob,
|
|
365
435
|
size: blob.size
|
|
366
436
|
});
|
|
437
|
+
if (!blobSliceProbe) {
|
|
438
|
+
probeBlobSliceReliability();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
createReadable(options) {
|
|
443
|
+
const reader = this;
|
|
444
|
+
const { blob, size } = reader;
|
|
445
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
446
|
+
if (!offset && readSize >= size) {
|
|
447
|
+
return blob.stream();
|
|
448
|
+
}
|
|
449
|
+
if (blobSliceReliable) {
|
|
450
|
+
return blob.slice(offset, offset + readSize).stream();
|
|
451
|
+
}
|
|
452
|
+
return super.createReadable(options);
|
|
367
453
|
}
|
|
368
454
|
|
|
369
455
|
async readUint8Array(offset, length) {
|
|
370
456
|
const reader = this;
|
|
371
457
|
const offsetEnd = offset + length;
|
|
372
|
-
const
|
|
458
|
+
const readsWholeBlob = !offset && offsetEnd >= reader.size;
|
|
459
|
+
const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
|
|
373
460
|
let arrayBuffer = await blob.arrayBuffer();
|
|
374
|
-
|
|
461
|
+
const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
|
|
462
|
+
if (sliceIgnoredByBuggyImplementation) {
|
|
375
463
|
arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
|
|
376
464
|
}
|
|
377
465
|
return new Uint8Array(arrayBuffer);
|
|
@@ -452,6 +540,18 @@
|
|
|
452
540
|
super.init();
|
|
453
541
|
}
|
|
454
542
|
|
|
543
|
+
createReadable(options) {
|
|
544
|
+
const reader = this;
|
|
545
|
+
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
546
|
+
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
547
|
+
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
548
|
+
if (readSize > 0 && offset < size) {
|
|
549
|
+
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return super.createReadable(options);
|
|
553
|
+
}
|
|
554
|
+
|
|
455
555
|
readUint8Array(index, length) {
|
|
456
556
|
return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
|
|
457
557
|
}
|
|
@@ -480,6 +580,8 @@
|
|
|
480
580
|
useRangeHeader,
|
|
481
581
|
forceRangeRequests,
|
|
482
582
|
combineSizeEocd,
|
|
583
|
+
checkResourceChanges = true,
|
|
584
|
+
maximumRangeSize = DEFAULT_MAXIMUM_RANGE_SIZE,
|
|
483
585
|
fetch
|
|
484
586
|
} = options;
|
|
485
587
|
options = Object.assign({}, options);
|
|
@@ -487,6 +589,8 @@
|
|
|
487
589
|
delete options.useRangeHeader;
|
|
488
590
|
delete options.forceRangeRequests;
|
|
489
591
|
delete options.combineSizeEocd;
|
|
592
|
+
delete options.checkResourceChanges;
|
|
593
|
+
delete options.maximumRangeSize;
|
|
490
594
|
delete options.useXHR;
|
|
491
595
|
delete options.fetch;
|
|
492
596
|
Object.assign(httpReader, {
|
|
@@ -496,6 +600,8 @@
|
|
|
496
600
|
useRangeHeader,
|
|
497
601
|
forceRangeRequests,
|
|
498
602
|
combineSizeEocd,
|
|
603
|
+
checkResourceChanges,
|
|
604
|
+
maximumRangeSize,
|
|
499
605
|
fetch
|
|
500
606
|
});
|
|
501
607
|
}
|
|
@@ -520,17 +626,8 @@
|
|
|
520
626
|
httpReader.eocdCache = eocdCache;
|
|
521
627
|
}
|
|
522
628
|
}
|
|
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
|
-
}
|
|
629
|
+
setResourceValidators(httpReader, response);
|
|
630
|
+
const contentSize = getContentRangeSize(response);
|
|
534
631
|
if (contentSize === UNDEFINED_VALUE) {
|
|
535
632
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
536
633
|
} else {
|
|
@@ -571,6 +668,8 @@
|
|
|
571
668
|
throw new Error(ERR_HTTP_RANGE);
|
|
572
669
|
}
|
|
573
670
|
}
|
|
671
|
+
checkResourceValidators(httpReader, response);
|
|
672
|
+
setResourceValidators(httpReader, response);
|
|
574
673
|
const data = new Uint8Array(await response.arrayBuffer());
|
|
575
674
|
if (data.length != length) {
|
|
576
675
|
throw new Error(ERR_HTTP_RANGE);
|
|
@@ -582,7 +681,114 @@
|
|
|
582
681
|
if (!data) {
|
|
583
682
|
await getRequestData(httpReader, options);
|
|
584
683
|
}
|
|
585
|
-
return
|
|
684
|
+
return httpReader.data.subarray(index, index + length);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
function createRangeReadable(httpReader, offset, size) {
|
|
689
|
+
let bodyReader;
|
|
690
|
+
let windowOffset = offset;
|
|
691
|
+
let windowRemainingLength = 0;
|
|
692
|
+
let remainingLength = size;
|
|
693
|
+
return new ReadableStream({
|
|
694
|
+
start() {
|
|
695
|
+
return openWindow();
|
|
696
|
+
},
|
|
697
|
+
async pull(controller) {
|
|
698
|
+
if (!bodyReader) {
|
|
699
|
+
await openWindow();
|
|
700
|
+
}
|
|
701
|
+
const { value, done } = await bodyReader.read();
|
|
702
|
+
if (done) {
|
|
703
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
704
|
+
}
|
|
705
|
+
const chunk = value.length > windowRemainingLength ? value.subarray(0, windowRemainingLength) : value;
|
|
706
|
+
windowRemainingLength -= chunk.length;
|
|
707
|
+
remainingLength -= chunk.length;
|
|
708
|
+
if (chunk.length) {
|
|
709
|
+
controller.enqueue(chunk);
|
|
710
|
+
}
|
|
711
|
+
if (!windowRemainingLength) {
|
|
712
|
+
await closeWindow();
|
|
713
|
+
if (!remainingLength) {
|
|
714
|
+
controller.close();
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
},
|
|
718
|
+
cancel(reason) {
|
|
719
|
+
return bodyReader && bodyReader.cancel(reason);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
async function openWindow() {
|
|
724
|
+
const windowLength = Math.min(httpReader.maximumRangeSize, remainingLength);
|
|
725
|
+
const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, windowOffset, windowLength));
|
|
726
|
+
if (response.status != 206) {
|
|
727
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
728
|
+
}
|
|
729
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
730
|
+
if (contentRangeHeader) {
|
|
731
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
732
|
+
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
733
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
checkResourceValidators(httpReader, response);
|
|
737
|
+
setResourceValidators(httpReader, response);
|
|
738
|
+
windowOffset += windowLength;
|
|
739
|
+
windowRemainingLength = windowLength;
|
|
740
|
+
bodyReader = response.body.getReader();
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
async function closeWindow() {
|
|
744
|
+
const currentBodyReader = bodyReader;
|
|
745
|
+
bodyReader = UNDEFINED_VALUE;
|
|
746
|
+
await currentBodyReader.cancel();
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
function getContentRangeSize(response) {
|
|
751
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
752
|
+
if (contentRangeHeader) {
|
|
753
|
+
const headerValue = contentRangeHeader.trim().split(/\s*\/\s*/)[1];
|
|
754
|
+
if (headerValue && headerValue != "*") {
|
|
755
|
+
const contentSize = Number(headerValue);
|
|
756
|
+
if (!Number.isNaN(contentSize)) {
|
|
757
|
+
return contentSize;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
function getResourceValidators({ headers }) {
|
|
764
|
+
return {
|
|
765
|
+
etag: headers.get(HTTP_HEADER_ETAG) || UNDEFINED_VALUE,
|
|
766
|
+
lastModified: headers.get(HTTP_HEADER_LAST_MODIFIED) || UNDEFINED_VALUE
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
function setResourceValidators(httpReader, response) {
|
|
771
|
+
const { checkResourceChanges, resourceValidators } = httpReader;
|
|
772
|
+
if (checkResourceChanges && !resourceValidators && response.status == 206) {
|
|
773
|
+
httpReader.resourceValidators = getResourceValidators(response);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
function checkResourceValidators(httpReader, response) {
|
|
778
|
+
const { checkResourceChanges, resourceValidators, size } = httpReader;
|
|
779
|
+
if (checkResourceChanges) {
|
|
780
|
+
const contentRangeSize = getContentRangeSize(response);
|
|
781
|
+
if (contentRangeSize !== UNDEFINED_VALUE && size !== UNDEFINED_VALUE && contentRangeSize != size) {
|
|
782
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
783
|
+
}
|
|
784
|
+
if (resourceValidators) {
|
|
785
|
+
const validators = getResourceValidators(response);
|
|
786
|
+
const changed = Object.entries(resourceValidators).some(([name, value]) =>
|
|
787
|
+
value !== UNDEFINED_VALUE && validators[name] !== UNDEFINED_VALUE && value != validators[name]);
|
|
788
|
+
if (changed) {
|
|
789
|
+
throw new Error(ERR_HTTP_RESOURCE_CHANGED);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
586
792
|
}
|
|
587
793
|
}
|
|
588
794
|
|
|
@@ -693,6 +899,10 @@
|
|
|
693
899
|
super.init();
|
|
694
900
|
}
|
|
695
901
|
|
|
902
|
+
createReadable(options) {
|
|
903
|
+
return this.reader.createReadable(options);
|
|
904
|
+
}
|
|
905
|
+
|
|
696
906
|
readUint8Array(index, length) {
|
|
697
907
|
return this.reader.readUint8Array(index, length);
|
|
698
908
|
}
|
|
@@ -766,25 +976,26 @@
|
|
|
766
976
|
const reader = this;
|
|
767
977
|
const { readers } = reader;
|
|
768
978
|
reader.lastDiskNumber = 0;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
if (indexDiskReader != readers.length - 1) {
|
|
773
|
-
reader.lastDiskOffset += diskReader.size;
|
|
774
|
-
}
|
|
979
|
+
await Promise.all(readers.map(diskReader => initStream(diskReader)));
|
|
980
|
+
reader.diskOffsets = readers.map(diskReader => {
|
|
981
|
+
const diskOffset = reader.size;
|
|
775
982
|
reader.size += diskReader.size;
|
|
776
|
-
|
|
983
|
+
return diskOffset;
|
|
984
|
+
});
|
|
777
985
|
super.init();
|
|
778
986
|
}
|
|
779
987
|
|
|
780
|
-
|
|
988
|
+
getDiskOffset(diskNumber) {
|
|
989
|
+
const { diskOffsets, size } = this;
|
|
990
|
+
const diskOffset = diskOffsets.at(diskNumber);
|
|
991
|
+
return diskOffset === UNDEFINED_VALUE ? size : diskOffset;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
async readUint8Array(offset, length) {
|
|
781
995
|
const reader = this;
|
|
782
996
|
const { readers } = this;
|
|
783
997
|
let result;
|
|
784
|
-
let currentDiskNumber =
|
|
785
|
-
if (currentDiskNumber == -1) {
|
|
786
|
-
currentDiskNumber = readers.length - 1;
|
|
787
|
-
}
|
|
998
|
+
let currentDiskNumber = 0;
|
|
788
999
|
let currentReaderOffset = offset;
|
|
789
1000
|
while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
|
|
790
1001
|
currentReaderOffset -= readers[currentDiskNumber].size;
|
|
@@ -797,14 +1008,9 @@
|
|
|
797
1008
|
result = await readUint8Array(currentReader, currentReaderOffset, length);
|
|
798
1009
|
} else {
|
|
799
1010
|
const chunkLength = currentReaderSize - currentReaderOffset;
|
|
800
|
-
result = new Uint8Array(length);
|
|
801
1011
|
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
|
-
}
|
|
1012
|
+
const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength);
|
|
1013
|
+
result = concat(firstPart, secondPart);
|
|
808
1014
|
}
|
|
809
1015
|
} else {
|
|
810
1016
|
result = EMPTY_UINT8_ARRAY;
|
|
@@ -829,6 +1035,12 @@
|
|
|
829
1035
|
let diskSourceWriter, diskWritable, diskWriter;
|
|
830
1036
|
const writable = new WritableStream({
|
|
831
1037
|
async write(chunk) {
|
|
1038
|
+
if (chunk === DISK_BOUNDARY) {
|
|
1039
|
+
if (diskWriter) {
|
|
1040
|
+
await endDisk();
|
|
1041
|
+
}
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
832
1044
|
const { availableSize } = writer;
|
|
833
1045
|
if (!diskWriter) {
|
|
834
1046
|
const { value, done } = await writerGenerator.next();
|
|
@@ -848,11 +1060,7 @@
|
|
|
848
1060
|
await this.write(chunk);
|
|
849
1061
|
} else if (chunk.length >= availableSize) {
|
|
850
1062
|
await writeChunk(chunk.subarray(0, availableSize));
|
|
851
|
-
await
|
|
852
|
-
writer.diskOffset += diskSourceWriter.size;
|
|
853
|
-
writer.diskNumber++;
|
|
854
|
-
diskWriter = null;
|
|
855
|
-
writer.availableSize = writer.maxSize;
|
|
1063
|
+
await endDisk();
|
|
856
1064
|
if (chunk.length > availableSize) {
|
|
857
1065
|
await this.write(chunk.subarray(availableSize));
|
|
858
1066
|
}
|
|
@@ -863,7 +1071,7 @@
|
|
|
863
1071
|
async close() {
|
|
864
1072
|
if (diskWriter) {
|
|
865
1073
|
await diskWriter.ready;
|
|
866
|
-
await
|
|
1074
|
+
await closeDiskWriter();
|
|
867
1075
|
}
|
|
868
1076
|
},
|
|
869
1077
|
async abort(reason) {
|
|
@@ -888,10 +1096,28 @@
|
|
|
888
1096
|
}
|
|
889
1097
|
}
|
|
890
1098
|
|
|
891
|
-
async function
|
|
1099
|
+
async function endDisk() {
|
|
1100
|
+
await closeDiskWriter();
|
|
1101
|
+
writer.diskOffset += diskSourceWriter.size;
|
|
1102
|
+
writer.diskNumber++;
|
|
1103
|
+
diskWriter = null;
|
|
1104
|
+
writer.availableSize = writer.maxSize;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
async function closeDiskWriter() {
|
|
892
1108
|
await diskWriter.close();
|
|
893
1109
|
}
|
|
894
1110
|
}
|
|
1111
|
+
|
|
1112
|
+
async closeDisk() {
|
|
1113
|
+
const streamWriter = this.writable.getWriter();
|
|
1114
|
+
try {
|
|
1115
|
+
await streamWriter.ready;
|
|
1116
|
+
await streamWriter.write(DISK_BOUNDARY);
|
|
1117
|
+
} finally {
|
|
1118
|
+
streamWriter.releaseLock();
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
895
1121
|
}
|
|
896
1122
|
|
|
897
1123
|
class GenericReader {
|
|
@@ -923,14 +1149,6 @@
|
|
|
923
1149
|
if (writer.size === UNDEFINED_VALUE) {
|
|
924
1150
|
writer.size = 0;
|
|
925
1151
|
}
|
|
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
1152
|
return writer;
|
|
935
1153
|
}
|
|
936
1154
|
}
|
|
@@ -949,8 +1167,8 @@
|
|
|
949
1167
|
}
|
|
950
1168
|
}
|
|
951
1169
|
|
|
952
|
-
function readUint8Array(reader, offset, size
|
|
953
|
-
return reader.readUint8Array(offset, size
|
|
1170
|
+
function readUint8Array(reader, offset, size) {
|
|
1171
|
+
return reader.readUint8Array(offset, size);
|
|
954
1172
|
}
|
|
955
1173
|
|
|
956
1174
|
/*
|
|
@@ -2239,16 +2457,6 @@
|
|
|
2239
2457
|
}
|
|
2240
2458
|
}
|
|
2241
2459
|
|
|
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
2460
|
function expand(inputArray, length) {
|
|
2253
2461
|
if (length && length > inputArray.length) {
|
|
2254
2462
|
const array = inputArray;
|
|
@@ -2510,44 +2718,34 @@
|
|
|
2510
2718
|
constructor() {
|
|
2511
2719
|
// deno-lint-ignore prefer-const
|
|
2512
2720
|
let stream;
|
|
2513
|
-
let
|
|
2514
|
-
let
|
|
2721
|
+
let headerBytesLeft = GZIP_HEADER_LENGTH;
|
|
2722
|
+
let trailerCandidate = new Uint8Array(0);
|
|
2515
2723
|
super({
|
|
2516
2724
|
transform(chunk, controller) {
|
|
2517
|
-
if (
|
|
2518
|
-
const
|
|
2519
|
-
|
|
2520
|
-
chunk = chunk.subarray(
|
|
2725
|
+
if (headerBytesLeft) {
|
|
2726
|
+
const droppedLength = Math.min(headerBytesLeft, chunk.length);
|
|
2727
|
+
headerBytesLeft -= droppedLength;
|
|
2728
|
+
chunk = chunk.subarray(droppedLength);
|
|
2521
2729
|
if (!chunk.length) {
|
|
2522
2730
|
return;
|
|
2523
2731
|
}
|
|
2524
2732
|
}
|
|
2525
|
-
const
|
|
2526
|
-
if (
|
|
2527
|
-
|
|
2528
|
-
pending.set(tail);
|
|
2529
|
-
pending.set(chunk, tail.length);
|
|
2530
|
-
tail = pending;
|
|
2733
|
+
const availableLength = trailerCandidate.length + chunk.length;
|
|
2734
|
+
if (availableLength <= GZIP_TRAILER_LENGTH) {
|
|
2735
|
+
trailerCandidate = concat(trailerCandidate, chunk);
|
|
2531
2736
|
return;
|
|
2532
2737
|
}
|
|
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;
|
|
2738
|
+
const emitLength = availableLength - GZIP_TRAILER_LENGTH;
|
|
2739
|
+
const emittedFromTrailer = Math.min(emitLength, trailerCandidate.length);
|
|
2740
|
+
controller.enqueue(concat(
|
|
2741
|
+
trailerCandidate.subarray(0, emittedFromTrailer),
|
|
2742
|
+
chunk.subarray(0, emitLength - emittedFromTrailer)));
|
|
2743
|
+
trailerCandidate = concat(
|
|
2744
|
+
trailerCandidate.subarray(emittedFromTrailer),
|
|
2745
|
+
chunk.subarray(emitLength - emittedFromTrailer));
|
|
2548
2746
|
},
|
|
2549
2747
|
flush() {
|
|
2550
|
-
const dataView =
|
|
2748
|
+
const dataView = getDataView(trailerCandidate);
|
|
2551
2749
|
stream.signature = dataView.getUint32(0, true);
|
|
2552
2750
|
stream.uncompressedSize = dataView.getUint32(4, true);
|
|
2553
2751
|
}
|
|
@@ -2790,33 +2988,54 @@
|
|
|
2790
2988
|
class ChunkStream extends TransformStream {
|
|
2791
2989
|
|
|
2792
2990
|
constructor(chunkSize) {
|
|
2793
|
-
|
|
2794
|
-
|
|
2991
|
+
const pendingChunks = [];
|
|
2992
|
+
let pendingLength = 0;
|
|
2993
|
+
if (!Number.isFinite(chunkSize) || chunkSize < 1) {
|
|
2795
2994
|
chunkSize = DEFAULT_CHUNK_SIZE;
|
|
2796
2995
|
}
|
|
2797
2996
|
super({
|
|
2798
|
-
transform,
|
|
2997
|
+
transform(chunk, controller) {
|
|
2998
|
+
pendingChunks.push(chunk);
|
|
2999
|
+
pendingLength += chunk.length;
|
|
3000
|
+
while (pendingLength > chunkSize) {
|
|
3001
|
+
controller.enqueue(shiftChunk());
|
|
3002
|
+
}
|
|
3003
|
+
},
|
|
2799
3004
|
flush(controller) {
|
|
2800
|
-
if (
|
|
2801
|
-
controller.enqueue(
|
|
3005
|
+
if (pendingLength) {
|
|
3006
|
+
controller.enqueue(concatChunks(pendingChunks, pendingLength));
|
|
2802
3007
|
}
|
|
2803
3008
|
}
|
|
2804
3009
|
});
|
|
2805
3010
|
|
|
2806
|
-
function
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
3011
|
+
function shiftChunk() {
|
|
3012
|
+
const result = new Uint8Array(chunkSize);
|
|
3013
|
+
let resultOffset = 0;
|
|
3014
|
+
while (resultOffset < chunkSize) {
|
|
3015
|
+
const firstChunk = pendingChunks[0];
|
|
3016
|
+
const remainingLength = chunkSize - resultOffset;
|
|
3017
|
+
if (firstChunk.length <= remainingLength) {
|
|
3018
|
+
result.set(firstChunk, resultOffset);
|
|
3019
|
+
resultOffset += firstChunk.length;
|
|
3020
|
+
pendingChunks.shift();
|
|
3021
|
+
} else {
|
|
3022
|
+
result.set(firstChunk.subarray(0, remainingLength), resultOffset);
|
|
3023
|
+
pendingChunks[0] = firstChunk.subarray(remainingLength);
|
|
3024
|
+
resultOffset += remainingLength;
|
|
3025
|
+
}
|
|
2813
3026
|
}
|
|
3027
|
+
pendingLength -= chunkSize;
|
|
3028
|
+
return result;
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
function concatChunks(chunks, length) {
|
|
3032
|
+
const result = new Uint8Array(length);
|
|
2814
3033
|
let offset = 0;
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
offset +=
|
|
3034
|
+
for (const chunk of chunks) {
|
|
3035
|
+
result.set(chunk, offset);
|
|
3036
|
+
offset += chunk.length;
|
|
2818
3037
|
}
|
|
2819
|
-
|
|
3038
|
+
return result;
|
|
2820
3039
|
}
|
|
2821
3040
|
}
|
|
2822
3041
|
}
|
|
@@ -2998,7 +3217,10 @@
|
|
|
2998
3217
|
}
|
|
2999
3218
|
}
|
|
3000
3219
|
codecStream = new CodecStream(options, config);
|
|
3001
|
-
await readable
|
|
3220
|
+
await readable
|
|
3221
|
+
.pipeThrough(codecStream)
|
|
3222
|
+
.pipeThrough(new ChunkStream(getChunkSize(config)))
|
|
3223
|
+
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
3002
3224
|
const {
|
|
3003
3225
|
signature,
|
|
3004
3226
|
inputSize,
|
|
@@ -3197,7 +3419,7 @@
|
|
|
3197
3419
|
const { value, readable, writable } = message;
|
|
3198
3420
|
const transferables = [];
|
|
3199
3421
|
if (value) {
|
|
3200
|
-
message.value =
|
|
3422
|
+
message.value = toExactUint8Array(value);
|
|
3201
3423
|
transferables.push(message.value.buffer);
|
|
3202
3424
|
}
|
|
3203
3425
|
if (transferStreams && transferStreamsSupported) {
|
|
@@ -3321,8 +3543,8 @@
|
|
|
3321
3543
|
const { options, config } = workerOptions;
|
|
3322
3544
|
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
3323
3545
|
const { workerURI, maxWorkers } = config;
|
|
3324
|
-
workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
|
|
3325
|
-
const streamCopy = !compressed && !signed && !encrypted
|
|
3546
|
+
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
3547
|
+
const streamCopy = !compressed && !signed && !encrypted;
|
|
3326
3548
|
workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
3327
3549
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
3328
3550
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
@@ -3791,7 +4013,7 @@
|
|
|
3791
4013
|
const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
|
|
3792
4014
|
if (!endOfDirectoryInfo) {
|
|
3793
4015
|
const signatureArray = await readUint8Array(reader, 0, 4);
|
|
3794
|
-
const signatureView = getDataView
|
|
4016
|
+
const signatureView = getDataView(signatureArray);
|
|
3795
4017
|
if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
|
|
3796
4018
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
3797
4019
|
} else {
|
|
@@ -3801,7 +4023,7 @@
|
|
|
3801
4023
|
if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
|
|
3802
4024
|
throwAmbiguousArchive("multiple end of central directory records");
|
|
3803
4025
|
}
|
|
3804
|
-
const endOfDirectoryView = getDataView
|
|
4026
|
+
const endOfDirectoryView = getDataView(endOfDirectoryInfo);
|
|
3805
4027
|
let directoryDataLength = getUint32(endOfDirectoryView, 12);
|
|
3806
4028
|
let directoryDataOffset = getUint32(endOfDirectoryView, 16);
|
|
3807
4029
|
const commentOffset = endOfDirectoryInfo.offset;
|
|
@@ -3817,17 +4039,21 @@
|
|
|
3817
4039
|
let prependedDataLength = 0;
|
|
3818
4040
|
let startOffset;
|
|
3819
4041
|
let zip64EndOfDirectory;
|
|
3820
|
-
|
|
4042
|
+
const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
|
|
4043
|
+
if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
|
|
4044
|
+
directoryDataOffset += getDiskOffset$1(reader, diskNumber);
|
|
4045
|
+
}
|
|
4046
|
+
if (requiresZip64) {
|
|
3821
4047
|
const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
|
|
3822
4048
|
await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
|
|
3823
4049
|
EMPTY_UINT8_ARRAY;
|
|
3824
|
-
const endOfDirectoryLocatorView = getDataView
|
|
4050
|
+
const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
|
|
3825
4051
|
if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
|
|
3826
4052
|
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
|
|
4053
|
+
directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4054
|
+
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4055
|
+
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4056
|
+
const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
3831
4057
|
if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
|
|
3832
4058
|
directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
|
|
3833
4059
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3835,8 +4061,8 @@
|
|
|
3835
4061
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3836
4062
|
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
3837
4063
|
}
|
|
3838
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH
|
|
3839
|
-
endOfDirectoryView = getDataView
|
|
4064
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4065
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
3840
4066
|
}
|
|
3841
4067
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
3842
4068
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -3862,7 +4088,7 @@
|
|
|
3862
4088
|
} else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
|
|
3863
4089
|
throwAmbiguousArchive("mismatched zip64 end of central directory record");
|
|
3864
4090
|
}
|
|
3865
|
-
directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4091
|
+
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
3866
4092
|
}
|
|
3867
4093
|
}
|
|
3868
4094
|
const declaredDirectoryDataLength = directoryDataLength;
|
|
@@ -3879,19 +4105,19 @@
|
|
|
3879
4105
|
throw new Error(ERR_BAD_FORMAT);
|
|
3880
4106
|
}
|
|
3881
4107
|
let offset = 0;
|
|
3882
|
-
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3883
|
-
let directoryView = getDataView
|
|
4108
|
+
let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4109
|
+
let directoryView = getDataView(directoryArray);
|
|
3884
4110
|
if (directoryDataLength) {
|
|
3885
4111
|
if (directoryArray.length < 4) {
|
|
3886
4112
|
throw new Error(ERR_BAD_FORMAT);
|
|
3887
4113
|
}
|
|
3888
|
-
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength
|
|
4114
|
+
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
3889
4115
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
3890
4116
|
const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3891
4117
|
let reconcile = !storedPointsAtDirectory;
|
|
3892
4118
|
if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
3893
|
-
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4
|
|
3894
|
-
reconcile = getUint32(getDataView
|
|
4119
|
+
const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
|
|
4120
|
+
reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
|
|
3895
4121
|
}
|
|
3896
4122
|
if (reconcile) {
|
|
3897
4123
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
@@ -3899,16 +4125,16 @@
|
|
|
3899
4125
|
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
3900
4126
|
prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
|
|
3901
4127
|
}
|
|
3902
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3903
|
-
directoryView = getDataView
|
|
4128
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4129
|
+
directoryView = getDataView(directoryArray);
|
|
3904
4130
|
}
|
|
3905
4131
|
}
|
|
3906
4132
|
}
|
|
3907
|
-
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset
|
|
4133
|
+
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
3908
4134
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
3909
4135
|
directoryDataLength = expectedDirectoryDataLength;
|
|
3910
|
-
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength
|
|
3911
|
-
directoryView = getDataView
|
|
4136
|
+
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4137
|
+
directoryView = getDataView(directoryArray);
|
|
3912
4138
|
}
|
|
3913
4139
|
if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
|
|
3914
4140
|
throw new Error(ERR_BAD_FORMAT);
|
|
@@ -3981,7 +4207,7 @@
|
|
|
3981
4207
|
});
|
|
3982
4208
|
readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
|
|
3983
4209
|
fileEntry.offset += prependedDataLength;
|
|
3984
|
-
startOffset = Math.min(fileEntry.offset, startOffset);
|
|
4210
|
+
startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
|
|
3985
4211
|
if (checkAmbiguity) {
|
|
3986
4212
|
if (filenames.has(fileEntry.filename)) {
|
|
3987
4213
|
duplicateFilename = true;
|
|
@@ -4095,8 +4321,9 @@
|
|
|
4095
4321
|
dataDescriptor
|
|
4096
4322
|
} = bitFlag;
|
|
4097
4323
|
const localDirectory = fileEntry.localDirectory = {};
|
|
4098
|
-
const
|
|
4099
|
-
const
|
|
4324
|
+
const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
|
|
4325
|
+
const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
|
|
4326
|
+
const dataView = getDataView(dataArray);
|
|
4100
4327
|
let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
|
|
4101
4328
|
let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
|
|
4102
4329
|
const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
|
|
@@ -4121,12 +4348,12 @@
|
|
|
4121
4348
|
const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
|
|
4122
4349
|
let rawLocalFilename = EMPTY_UINT8_ARRAY;
|
|
4123
4350
|
if (checkAmbiguity && (filenameLength || extraFieldLength)) {
|
|
4124
|
-
const trailingDataArray = await readUint8Array(reader,
|
|
4351
|
+
const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
|
|
4125
4352
|
rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
|
|
4126
4353
|
localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
|
|
4127
4354
|
} else {
|
|
4128
4355
|
localDirectory.rawExtraField = extraFieldLength ?
|
|
4129
|
-
await readUint8Array(reader,
|
|
4356
|
+
await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
|
|
4130
4357
|
EMPTY_UINT8_ARRAY;
|
|
4131
4358
|
}
|
|
4132
4359
|
readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
|
|
@@ -4152,9 +4379,9 @@
|
|
|
4152
4379
|
throw new Error(ERR_ENCRYPTED);
|
|
4153
4380
|
}
|
|
4154
4381
|
}
|
|
4155
|
-
const dataOffset =
|
|
4382
|
+
const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
|
|
4156
4383
|
const size = compressedSize;
|
|
4157
|
-
const readable = reader.createReadable({ offset: dataOffset, size
|
|
4384
|
+
const readable = reader.createReadable({ offset: dataOffset, size });
|
|
4158
4385
|
const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
|
|
4159
4386
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
4160
4387
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -4195,8 +4422,7 @@
|
|
|
4195
4422
|
reader,
|
|
4196
4423
|
fileEntry,
|
|
4197
4424
|
index,
|
|
4198
|
-
offset,
|
|
4199
|
-
diskNumberStart,
|
|
4425
|
+
offset: localHeaderOffset,
|
|
4200
4426
|
signature,
|
|
4201
4427
|
compressedSize,
|
|
4202
4428
|
uncompressedSize,
|
|
@@ -4260,7 +4486,7 @@
|
|
|
4260
4486
|
function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
|
|
4261
4487
|
const { rawExtraField } = directory;
|
|
4262
4488
|
const extraField = directory.extraField = new Map();
|
|
4263
|
-
const rawExtraFieldView = getDataView
|
|
4489
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
4264
4490
|
let offsetExtraField = 0;
|
|
4265
4491
|
try {
|
|
4266
4492
|
while (offsetExtraField < rawExtraField.length) {
|
|
@@ -4332,7 +4558,7 @@
|
|
|
4332
4558
|
|
|
4333
4559
|
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
4334
4560
|
directory.zip64 = true;
|
|
4335
|
-
const extraFieldView = getDataView
|
|
4561
|
+
const extraFieldView = getDataView(extraFieldZip64.data);
|
|
4336
4562
|
const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
|
|
4337
4563
|
const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
|
|
4338
4564
|
if (extraFieldZip64.data.length < requiredLength) {
|
|
@@ -4351,10 +4577,10 @@
|
|
|
4351
4577
|
extraFieldUnicode.valid = false;
|
|
4352
4578
|
return;
|
|
4353
4579
|
}
|
|
4354
|
-
const extraFieldView = getDataView
|
|
4580
|
+
const extraFieldView = getDataView(extraFieldUnicode.data);
|
|
4355
4581
|
const crc32 = new Crc32();
|
|
4356
4582
|
crc32.append(fileEntry[rawPropertyName]);
|
|
4357
|
-
const dataViewSignature = getDataView
|
|
4583
|
+
const dataViewSignature = getDataView(new Uint8Array(4));
|
|
4358
4584
|
dataViewSignature.setUint32(0, crc32.get(), true);
|
|
4359
4585
|
const signature = getUint32(extraFieldView, 1);
|
|
4360
4586
|
Object.assign(extraFieldUnicode, {
|
|
@@ -4369,7 +4595,7 @@
|
|
|
4369
4595
|
}
|
|
4370
4596
|
|
|
4371
4597
|
function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
|
|
4372
|
-
const extraFieldView = getDataView
|
|
4598
|
+
const extraFieldView = getDataView(extraFieldAES.data);
|
|
4373
4599
|
const strength = getUint8(extraFieldView, 4);
|
|
4374
4600
|
Object.assign(extraFieldAES, {
|
|
4375
4601
|
vendorVersion: getUint8(extraFieldView, 0),
|
|
@@ -4382,7 +4608,7 @@
|
|
|
4382
4608
|
}
|
|
4383
4609
|
|
|
4384
4610
|
function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
4385
|
-
const extraFieldView = getDataView
|
|
4611
|
+
const extraFieldView = getDataView(extraFieldNTFS.data);
|
|
4386
4612
|
let offsetExtraField = 4;
|
|
4387
4613
|
let tag1Data;
|
|
4388
4614
|
try {
|
|
@@ -4399,7 +4625,7 @@
|
|
|
4399
4625
|
}
|
|
4400
4626
|
try {
|
|
4401
4627
|
if (tag1Data && tag1Data.length == 24) {
|
|
4402
|
-
const tag1View = getDataView
|
|
4628
|
+
const tag1View = getDataView(tag1Data);
|
|
4403
4629
|
const rawLastModDate = tag1View.getBigUint64(0, true);
|
|
4404
4630
|
const rawLastAccessDate = tag1View.getBigUint64(8, true);
|
|
4405
4631
|
const rawCreationDate = tag1View.getBigUint64(16, true);
|
|
@@ -4422,7 +4648,7 @@
|
|
|
4422
4648
|
|
|
4423
4649
|
function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
4424
4650
|
try {
|
|
4425
|
-
const view = getDataView
|
|
4651
|
+
const view = getDataView(extraField.data);
|
|
4426
4652
|
let uid, gid;
|
|
4427
4653
|
if (isInfoZip) {
|
|
4428
4654
|
let offset = 0;
|
|
@@ -4460,7 +4686,7 @@
|
|
|
4460
4686
|
if (!extraFieldExtendedTimestamp.data.length) {
|
|
4461
4687
|
return;
|
|
4462
4688
|
}
|
|
4463
|
-
const extraFieldView = getDataView
|
|
4689
|
+
const extraFieldView = getDataView(extraFieldExtendedTimestamp.data);
|
|
4464
4690
|
const flags = getUint8(extraFieldView, 0);
|
|
4465
4691
|
const timeProperties = [];
|
|
4466
4692
|
const timeRawProperties = [];
|
|
@@ -4498,7 +4724,6 @@
|
|
|
4498
4724
|
fileEntry,
|
|
4499
4725
|
index,
|
|
4500
4726
|
offset,
|
|
4501
|
-
diskNumberStart,
|
|
4502
4727
|
signature,
|
|
4503
4728
|
compressedSize,
|
|
4504
4729
|
uncompressedSize,
|
|
@@ -4507,12 +4732,6 @@
|
|
|
4507
4732
|
extraFieldZip64,
|
|
4508
4733
|
readRanges
|
|
4509
4734
|
}) {
|
|
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
4735
|
let dataDescriptorLength = 0;
|
|
4517
4736
|
if (dataDescriptor) {
|
|
4518
4737
|
if (extraFieldZip64) {
|
|
@@ -4522,19 +4741,19 @@
|
|
|
4522
4741
|
}
|
|
4523
4742
|
}
|
|
4524
4743
|
if (dataDescriptorLength) {
|
|
4525
|
-
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH
|
|
4744
|
+
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
4526
4745
|
const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
4527
|
-
getUint32(getDataView
|
|
4746
|
+
getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
4528
4747
|
if (dataDescriptorSignature) {
|
|
4529
|
-
const readSignature = getUint32(getDataView
|
|
4748
|
+
const readSignature = getUint32(getDataView(dataDescriptorArray), 4);
|
|
4530
4749
|
let readCompressedSize;
|
|
4531
4750
|
let readUncompressedSize;
|
|
4532
4751
|
if (extraFieldZip64) {
|
|
4533
|
-
readCompressedSize = getBigUint64(getDataView
|
|
4534
|
-
readUncompressedSize = getBigUint64(getDataView
|
|
4752
|
+
readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
|
|
4753
|
+
readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
|
|
4535
4754
|
} else {
|
|
4536
|
-
readCompressedSize = getUint32(getDataView
|
|
4537
|
-
readUncompressedSize = getUint32(getDataView
|
|
4755
|
+
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
4756
|
+
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
4538
4757
|
}
|
|
4539
4758
|
const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
|
|
4540
4759
|
if (matchSignature &&
|
|
@@ -4545,8 +4764,8 @@
|
|
|
4545
4764
|
}
|
|
4546
4765
|
}
|
|
4547
4766
|
const range = {
|
|
4548
|
-
start:
|
|
4549
|
-
end:
|
|
4767
|
+
start: offset,
|
|
4768
|
+
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
4550
4769
|
fileEntry
|
|
4551
4770
|
};
|
|
4552
4771
|
for (const [otherIndex, otherRange] of readRanges) {
|
|
@@ -4559,6 +4778,10 @@
|
|
|
4559
4778
|
readRanges.set(index, range);
|
|
4560
4779
|
}
|
|
4561
4780
|
|
|
4781
|
+
function getDiskOffset$1(reader, diskNumber) {
|
|
4782
|
+
return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
|
|
4783
|
+
}
|
|
4784
|
+
|
|
4562
4785
|
function getStrictness(strictness, checkAmbiguity) {
|
|
4563
4786
|
if (strictness === UNDEFINED_VALUE) {
|
|
4564
4787
|
return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
|
|
@@ -4642,7 +4865,7 @@
|
|
|
4642
4865
|
async function* scanEndOfCentralDirectory(reader, scanLength) {
|
|
4643
4866
|
const scanOffset = reader.size - scanLength;
|
|
4644
4867
|
const scanArray = await readUint8Array(reader, scanOffset, scanLength);
|
|
4645
|
-
const scanView = getDataView
|
|
4868
|
+
const scanView = getDataView(scanArray);
|
|
4646
4869
|
for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
4647
4870
|
if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4648
4871
|
yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
|
|
@@ -4665,7 +4888,8 @@
|
|
|
4665
4888
|
if (!filesLength && !directoryDataLength) {
|
|
4666
4889
|
return CENTRAL_DIRECTORY_PLAUSIBLE;
|
|
4667
4890
|
}
|
|
4668
|
-
|
|
4891
|
+
const directoryDiskNumber = getUint16(view, indexByte + 6);
|
|
4892
|
+
for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
|
|
4669
4893
|
if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4670
4894
|
return CENTRAL_DIRECTORY_REACHABLE;
|
|
4671
4895
|
}
|
|
@@ -4683,7 +4907,7 @@
|
|
|
4683
4907
|
if (remoteProbeBudget.count > 0) {
|
|
4684
4908
|
remoteProbeBudget.count--;
|
|
4685
4909
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
4686
|
-
return getUint32(getDataView
|
|
4910
|
+
return getUint32(getDataView(signatureArray), 0);
|
|
4687
4911
|
}
|
|
4688
4912
|
return UNDEFINED_VALUE;
|
|
4689
4913
|
}
|
|
@@ -4748,9 +4972,26 @@
|
|
|
4748
4972
|
return Number(view.getBigUint64(offset, true));
|
|
4749
4973
|
}
|
|
4750
4974
|
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4975
|
+
var zipReader = /*#__PURE__*/Object.freeze({
|
|
4976
|
+
__proto__: null,
|
|
4977
|
+
ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
|
|
4978
|
+
ERR_BAD_FORMAT: ERR_BAD_FORMAT,
|
|
4979
|
+
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
4980
|
+
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
4981
|
+
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
4982
|
+
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
4983
|
+
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
4984
|
+
ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
|
|
4985
|
+
ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
|
|
4986
|
+
ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
|
|
4987
|
+
ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
|
|
4988
|
+
ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
|
|
4989
|
+
ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
|
|
4990
|
+
ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
|
|
4991
|
+
ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
|
|
4992
|
+
ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
|
|
4993
|
+
ZipReader: ZipReader
|
|
4994
|
+
});
|
|
4754
4995
|
|
|
4755
4996
|
/*
|
|
4756
4997
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -4815,9 +5056,10 @@
|
|
|
4815
5056
|
|
|
4816
5057
|
constructor(writer, options = {}) {
|
|
4817
5058
|
writer = new GenericWriter(writer);
|
|
5059
|
+
const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
|
|
4818
5060
|
const addSplitZipSignature =
|
|
4819
|
-
|
|
4820
|
-
|
|
5061
|
+
availableSize > 0 && availableSize !== INFINITY_VALUE &&
|
|
5062
|
+
maxSize > 0 && maxSize !== INFINITY_VALUE;
|
|
4821
5063
|
Object.assign(this, {
|
|
4822
5064
|
writer,
|
|
4823
5065
|
addSplitZipSignature,
|
|
@@ -4839,9 +5081,10 @@
|
|
|
4839
5081
|
}
|
|
4840
5082
|
reader = new GenericReader(reader);
|
|
4841
5083
|
await initStream(reader);
|
|
4842
|
-
const
|
|
4843
|
-
const
|
|
4844
|
-
await zipReader.
|
|
5084
|
+
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
5085
|
+
const zipReader$1 = new ZipReader(reader.readable);
|
|
5086
|
+
const entries = await zipReader$1.getEntries();
|
|
5087
|
+
await zipReader$1.close();
|
|
4845
5088
|
await initStream(this.writer);
|
|
4846
5089
|
await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
|
|
4847
5090
|
this.writer.size = this.offset = reader.size;
|
|
@@ -4857,8 +5100,6 @@
|
|
|
4857
5100
|
encrypted,
|
|
4858
5101
|
uncompressedSize,
|
|
4859
5102
|
compressedSize,
|
|
4860
|
-
diskOffset,
|
|
4861
|
-
diskNumber,
|
|
4862
5103
|
zip64
|
|
4863
5104
|
} = entry;
|
|
4864
5105
|
let {
|
|
@@ -4906,8 +5147,9 @@
|
|
|
4906
5147
|
Object.assign(entry, {
|
|
4907
5148
|
zip64UncompressedSize,
|
|
4908
5149
|
zip64CompressedSize,
|
|
4909
|
-
zip64Offset: zip64 &&
|
|
4910
|
-
|
|
5150
|
+
zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
|
|
5151
|
+
diskNumberStart: 0,
|
|
5152
|
+
zip64DiskNumberStart: false,
|
|
4911
5153
|
rawExtraFieldZip64,
|
|
4912
5154
|
rawExtraFieldAES,
|
|
4913
5155
|
rawExtraFieldExtendedTimestamp,
|
|
@@ -5012,7 +5254,8 @@
|
|
|
5012
5254
|
try {
|
|
5013
5255
|
const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
|
|
5014
5256
|
({ reader } = sizesInfo);
|
|
5015
|
-
const
|
|
5257
|
+
const diskOffset = getDiskOffset(zipWriter.writer);
|
|
5258
|
+
const diskNumber = getDiskNumber(zipWriter.writer);
|
|
5016
5259
|
options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
|
|
5017
5260
|
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
5018
5261
|
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
@@ -5189,7 +5432,7 @@
|
|
|
5189
5432
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
5190
5433
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
5191
5434
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
5192
|
-
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS
|
|
5435
|
+
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
5193
5436
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
5194
5437
|
const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
5195
5438
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
@@ -5387,7 +5630,7 @@
|
|
|
5387
5630
|
await requestLockWriter();
|
|
5388
5631
|
}
|
|
5389
5632
|
await initStream(fileWriter);
|
|
5390
|
-
const
|
|
5633
|
+
const diskOffset = getDiskOffset(writer);
|
|
5391
5634
|
if (zipWriter.addSplitZipSignature) {
|
|
5392
5635
|
delete zipWriter.addSplitZipSignature;
|
|
5393
5636
|
const signatureArray = new Uint8Array(4);
|
|
@@ -5404,7 +5647,7 @@
|
|
|
5404
5647
|
await lockPreviousFileEntry;
|
|
5405
5648
|
await skipDiskIfNeeded();
|
|
5406
5649
|
}
|
|
5407
|
-
const diskNumberStart = writer
|
|
5650
|
+
const diskNumberStart = getDiskNumber(writer);
|
|
5408
5651
|
const entryOffset = getSegmentOffset(zipWriter, writer);
|
|
5409
5652
|
fileEntry.diskNumberStart = diskNumberStart;
|
|
5410
5653
|
if (!bufferedWrite) {
|
|
@@ -5424,11 +5667,11 @@
|
|
|
5424
5667
|
writingBufferedEntryData = true;
|
|
5425
5668
|
writerSizeBeforeEntry = writer.size;
|
|
5426
5669
|
await skipDiskIfNeeded();
|
|
5427
|
-
fileEntry.diskNumberStart = writer
|
|
5670
|
+
fileEntry.diskNumberStart = getDiskNumber(writer);
|
|
5428
5671
|
fileEntry.offset = getSegmentOffset(zipWriter, writer);
|
|
5429
5672
|
if (usdz) {
|
|
5430
5673
|
const previousMetadataSize = entryInfo.metadataSize;
|
|
5431
|
-
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer
|
|
5674
|
+
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
|
|
5432
5675
|
fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
|
|
5433
5676
|
}
|
|
5434
5677
|
updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
|
|
@@ -5493,9 +5736,8 @@
|
|
|
5493
5736
|
}
|
|
5494
5737
|
|
|
5495
5738
|
async function skipDiskIfNeeded() {
|
|
5496
|
-
if (getLength(headerInfo.localHeaderArray)
|
|
5497
|
-
writer.
|
|
5498
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
5739
|
+
if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
|
|
5740
|
+
await writer.closeDisk();
|
|
5499
5741
|
}
|
|
5500
5742
|
}
|
|
5501
5743
|
}
|
|
@@ -5606,7 +5848,7 @@
|
|
|
5606
5848
|
}
|
|
5607
5849
|
const { writable } = writer;
|
|
5608
5850
|
if (reader) {
|
|
5609
|
-
const readable = reader.createReadable ? reader.createReadable(
|
|
5851
|
+
const readable = reader.createReadable ? reader.createReadable() : reader.readable;
|
|
5610
5852
|
const size = reader.size;
|
|
5611
5853
|
const workerOptions = {
|
|
5612
5854
|
options: {
|
|
@@ -6038,8 +6280,8 @@
|
|
|
6038
6280
|
|
|
6039
6281
|
async function closeFile(zipWriter, comment, options) {
|
|
6040
6282
|
const directoryDataLength = createDirectoryRecords(zipWriter.files);
|
|
6041
|
-
const
|
|
6042
|
-
await writeEndOfDirectoryRecord(zipWriter, comment, options, {
|
|
6283
|
+
const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
|
|
6284
|
+
await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
|
|
6043
6285
|
}
|
|
6044
6286
|
|
|
6045
6287
|
function createDirectoryRecords(files) {
|
|
@@ -6121,8 +6363,8 @@
|
|
|
6121
6363
|
await initStream(writer);
|
|
6122
6364
|
let offset = 0;
|
|
6123
6365
|
let directoryDiskOffset = 0;
|
|
6124
|
-
let
|
|
6125
|
-
let
|
|
6366
|
+
let directoryStartDiskNumber = getDiskNumber(writer);
|
|
6367
|
+
let directoryStartDiskOffset = getDiskOffset(writer);
|
|
6126
6368
|
for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
|
|
6127
6369
|
const {
|
|
6128
6370
|
offset: fileEntryOffset,
|
|
@@ -6149,15 +6391,14 @@
|
|
|
6149
6391
|
} = fileEntry;
|
|
6150
6392
|
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6151
6393
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
6152
|
-
if (offset + directoryRecordLength - directoryDiskOffset
|
|
6394
|
+
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
6153
6395
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
6154
6396
|
directoryDiskOffset = offset;
|
|
6155
|
-
writer.
|
|
6156
|
-
await writeData(writer, EMPTY_UINT8_ARRAY);
|
|
6397
|
+
await writer.closeDisk();
|
|
6157
6398
|
}
|
|
6158
6399
|
if (indexFileEntry == 0) {
|
|
6159
|
-
|
|
6160
|
-
|
|
6400
|
+
directoryStartDiskNumber = getDiskNumber(writer);
|
|
6401
|
+
directoryStartDiskOffset = getDiskOffset(writer);
|
|
6161
6402
|
}
|
|
6162
6403
|
if (!zip64UncompressedSize) {
|
|
6163
6404
|
setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
|
|
@@ -6197,18 +6438,18 @@
|
|
|
6197
6438
|
}
|
|
6198
6439
|
}
|
|
6199
6440
|
await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
6200
|
-
return {
|
|
6441
|
+
return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
|
|
6201
6442
|
}
|
|
6202
6443
|
|
|
6203
6444
|
async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
|
|
6204
6445
|
const { writer } = zipWriter;
|
|
6205
|
-
const {
|
|
6446
|
+
const { directoryStart } = cdInfo;
|
|
6206
6447
|
let { directoryDataLength } = cdInfo;
|
|
6207
6448
|
let filesLength = zipWriter.files.size;
|
|
6208
|
-
let diskNumber =
|
|
6209
|
-
let directoryOffset =
|
|
6210
|
-
let lastDiskNumber = writer
|
|
6211
|
-
if (writer
|
|
6449
|
+
let diskNumber = directoryStart.diskNumber;
|
|
6450
|
+
let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
|
|
6451
|
+
let lastDiskNumber = getDiskNumber(writer);
|
|
6452
|
+
if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
|
|
6212
6453
|
lastDiskNumber++;
|
|
6213
6454
|
}
|
|
6214
6455
|
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
@@ -6224,11 +6465,10 @@
|
|
|
6224
6465
|
throw new Error(ERR_INVALID_COMMENT);
|
|
6225
6466
|
}
|
|
6226
6467
|
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);
|
|
6468
|
+
if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
|
|
6469
|
+
await writer.closeDisk();
|
|
6230
6470
|
}
|
|
6231
|
-
lastDiskNumber = writer
|
|
6471
|
+
lastDiskNumber = getDiskNumber(writer);
|
|
6232
6472
|
if (zip64) {
|
|
6233
6473
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
6234
6474
|
endOfdirectoryRecord.uint64(44);
|
|
@@ -6242,7 +6482,7 @@
|
|
|
6242
6482
|
endOfdirectoryRecord.uint64(directoryOffset);
|
|
6243
6483
|
endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
6244
6484
|
endOfdirectoryRecord.uint32(lastDiskNumber);
|
|
6245
|
-
endOfdirectoryRecord.uint64(BigInt(zipWriter
|
|
6485
|
+
endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
|
|
6246
6486
|
endOfdirectoryRecord.uint32(lastDiskNumber + 1);
|
|
6247
6487
|
const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
|
|
6248
6488
|
if (supportZip64SplitFile) {
|
|
@@ -6282,8 +6522,23 @@
|
|
|
6282
6522
|
};
|
|
6283
6523
|
}
|
|
6284
6524
|
|
|
6285
|
-
function
|
|
6286
|
-
|
|
6525
|
+
function getDiskNumber(writer) {
|
|
6526
|
+
const { diskNumber = 0 } = writer;
|
|
6527
|
+
return diskNumber;
|
|
6528
|
+
}
|
|
6529
|
+
|
|
6530
|
+
function getDiskOffset(writer) {
|
|
6531
|
+
const { diskOffset = 0 } = writer;
|
|
6532
|
+
return diskOffset;
|
|
6533
|
+
}
|
|
6534
|
+
|
|
6535
|
+
function exceedsAvailableSize(writer, length) {
|
|
6536
|
+
const { availableSize = INFINITY_VALUE } = writer;
|
|
6537
|
+
return length > availableSize;
|
|
6538
|
+
}
|
|
6539
|
+
|
|
6540
|
+
function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
|
|
6541
|
+
return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
|
|
6287
6542
|
}
|
|
6288
6543
|
|
|
6289
6544
|
async function writeData(writer, array) {
|
|
@@ -6360,9 +6615,6 @@
|
|
|
6360
6615
|
array.set(typedArray, offset);
|
|
6361
6616
|
}
|
|
6362
6617
|
|
|
6363
|
-
function getDataView(array) {
|
|
6364
|
-
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
6365
|
-
}
|
|
6366
6618
|
|
|
6367
6619
|
function getLength(...arrayLikes) {
|
|
6368
6620
|
let result = 0;
|
|
@@ -6620,9 +6872,7 @@
|
|
|
6620
6872
|
|
|
6621
6873
|
async getArrayBuffer(options) {
|
|
6622
6874
|
const array = await this.getUint8Array(options);
|
|
6623
|
-
return array.
|
|
6624
|
-
? array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength)
|
|
6625
|
-
: array.buffer;
|
|
6875
|
+
return toExactUint8Array(array).buffer;
|
|
6626
6876
|
}
|
|
6627
6877
|
|
|
6628
6878
|
replaceBlob(blob) {
|