@zip.js/zip.js 2.19.0 → 2.21.0
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/BENCHMARKS.md +154 -130
- package/deno.json +1 -1
- package/dist/zip-core-external.js +440 -225
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +441 -224
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +440 -225
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +441 -224
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +440 -225
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +441 -224
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +441 -224
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +441 -224
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +441 -224
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +441 -224
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +441 -224
- package/index-native.min.js +1 -1
- package/index.cjs +441 -224
- package/index.d.cts +117 -24
- package/index.d.ts +117 -24
- package/index.min.js +1 -1
- package/lib/core/constants.js +7 -0
- package/lib/core/version.js +1 -1
- package/lib/core/zip-reader.js +225 -76
- package/lib/core/zip-writer.js +214 -147
- package/lib/zip-core-reader.js +2 -0
- package/package.json +1 -1
package/lib/core/zip-writer.js
CHANGED
|
@@ -114,7 +114,6 @@ import {
|
|
|
114
114
|
BITFLAG_ENCRYPTED,
|
|
115
115
|
BITFLAG_DATA_DESCRIPTOR,
|
|
116
116
|
BITFLAG_LANG_ENCODING_FLAG,
|
|
117
|
-
BITFLAG_LEVEL,
|
|
118
117
|
BITFLAG_LEVEL_FAST_MASK,
|
|
119
118
|
BITFLAG_LEVEL_SUPER_FAST_MASK,
|
|
120
119
|
BITFLAG_LEVEL_MAX_MASK,
|
|
@@ -140,6 +139,9 @@ import {
|
|
|
140
139
|
VERSION_AES,
|
|
141
140
|
DIRECTORY_SIGNATURE,
|
|
142
141
|
HEADER_SIZE,
|
|
142
|
+
ERR_LOCAL_FILE_HEADER_NOT_FOUND,
|
|
143
|
+
ERR_OVERLAPPING_ENTRY,
|
|
144
|
+
ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
143
145
|
HEADER_OFFSET_VERSION,
|
|
144
146
|
HEADER_OFFSET_SIGNATURE,
|
|
145
147
|
HEADER_OFFSET_COMPRESSED_SIZE,
|
|
@@ -342,130 +344,8 @@ class ZipWriter {
|
|
|
342
344
|
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
343
345
|
}
|
|
344
346
|
|
|
345
|
-
appendZip(reader) {
|
|
346
|
-
return watchPromiseError(this,
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
async appendZipEntries(reader) {
|
|
350
|
-
const zipWriter = this;
|
|
351
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
352
|
-
while (pendingAddFileCalls.size) {
|
|
353
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
354
|
-
}
|
|
355
|
-
let resolveAppendZip;
|
|
356
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
357
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
358
|
-
const appendedFilenames = [];
|
|
359
|
-
let releaseLockWriter;
|
|
360
|
-
try {
|
|
361
|
-
reader = new GenericReader(reader);
|
|
362
|
-
await initStream(reader);
|
|
363
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
364
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
365
|
-
await initStream(reader);
|
|
366
|
-
}
|
|
367
|
-
const { ZipReader } = await import("./zip-reader.js");
|
|
368
|
-
const zipReader = new ZipReader(reader);
|
|
369
|
-
const entries = await zipReader.getEntries();
|
|
370
|
-
await zipReader.close();
|
|
371
|
-
await initStream(zipWriter.writer);
|
|
372
|
-
const { directoryOffset } = zipReader;
|
|
373
|
-
entries.forEach(({ filename }) => {
|
|
374
|
-
if (filenames.has(filename)) {
|
|
375
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
376
|
-
}
|
|
377
|
-
filenames.add(filename);
|
|
378
|
-
appendedFilenames.push(filename);
|
|
379
|
-
});
|
|
380
|
-
zipWriter.writerLocked = true;
|
|
381
|
-
const { lockWriter } = zipWriter;
|
|
382
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
383
|
-
zipWriter.writerLocked = false;
|
|
384
|
-
resolve();
|
|
385
|
-
});
|
|
386
|
-
await lockWriter;
|
|
387
|
-
if (zipWriter.addSplitZipSignature) {
|
|
388
|
-
delete zipWriter.addSplitZipSignature;
|
|
389
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
390
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
391
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
395
|
-
entries.forEach(entry => {
|
|
396
|
-
const {
|
|
397
|
-
version,
|
|
398
|
-
rawLastModDate,
|
|
399
|
-
rawFilename,
|
|
400
|
-
bitFlag,
|
|
401
|
-
encrypted,
|
|
402
|
-
uncompressedSize,
|
|
403
|
-
compressedSize,
|
|
404
|
-
extraFieldZip64
|
|
405
|
-
} = entry;
|
|
406
|
-
let {
|
|
407
|
-
compressionMethod,
|
|
408
|
-
rawExtraField,
|
|
409
|
-
} = entry;
|
|
410
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
411
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
412
|
-
if (entry.extraFieldAES) {
|
|
413
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
414
|
-
}
|
|
415
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
416
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
417
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
418
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
419
|
-
const {
|
|
420
|
-
headerArray,
|
|
421
|
-
headerView
|
|
422
|
-
} = getHeaderArrayData({
|
|
423
|
-
version,
|
|
424
|
-
bitFlag: bitFlagValue,
|
|
425
|
-
compressionMethod,
|
|
426
|
-
uncompressedSize,
|
|
427
|
-
compressedSize,
|
|
428
|
-
rawLastModDate,
|
|
429
|
-
rawFilename,
|
|
430
|
-
zip64CompressedSize,
|
|
431
|
-
zip64UncompressedSize,
|
|
432
|
-
extraFieldLength
|
|
433
|
-
});
|
|
434
|
-
const { crc32 } = entry;
|
|
435
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
436
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
437
|
-
}
|
|
438
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
439
|
-
Object.assign(entry, {
|
|
440
|
-
zip64Enabled: true,
|
|
441
|
-
zip64UncompressedSize,
|
|
442
|
-
zip64CompressedSize,
|
|
443
|
-
offset,
|
|
444
|
-
diskNumberStart,
|
|
445
|
-
zip64DiskNumberStart: false,
|
|
446
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
447
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
448
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
449
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
450
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
451
|
-
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
452
|
-
rawExtraField,
|
|
453
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
454
|
-
headerArray,
|
|
455
|
-
headerView
|
|
456
|
-
});
|
|
457
|
-
fileEntries.set(entry.filename, entry);
|
|
458
|
-
});
|
|
459
|
-
} catch (error) {
|
|
460
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
461
|
-
throw error;
|
|
462
|
-
} finally {
|
|
463
|
-
resolveAppendZip();
|
|
464
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
465
|
-
if (releaseLockWriter) {
|
|
466
|
-
releaseLockWriter();
|
|
467
|
-
}
|
|
468
|
-
}
|
|
347
|
+
appendZip(reader, options = {}) {
|
|
348
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
469
349
|
}
|
|
470
350
|
|
|
471
351
|
add(name = "", reader, options = {}) {
|
|
@@ -627,11 +507,140 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
627
507
|
return watchedPromise;
|
|
628
508
|
}
|
|
629
509
|
|
|
510
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
511
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
512
|
+
const filter = checkFunctionOption(options.filter);
|
|
513
|
+
while (pendingAddFileCalls.size) {
|
|
514
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
515
|
+
}
|
|
516
|
+
let resolveAppendZip;
|
|
517
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
518
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
519
|
+
const appendedFilenames = [];
|
|
520
|
+
let releaseLockWriter;
|
|
521
|
+
try {
|
|
522
|
+
reader = new GenericReader(reader);
|
|
523
|
+
await initStream(reader);
|
|
524
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
525
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
526
|
+
await initStream(reader);
|
|
527
|
+
}
|
|
528
|
+
const { ZipReader, getEntryDataDescriptorLength } = await import("./zip-reader.js");
|
|
529
|
+
const zipReader = new ZipReader(reader);
|
|
530
|
+
const entries = await zipReader.getEntries();
|
|
531
|
+
const keptEntries = [];
|
|
532
|
+
for (const entry of entries) {
|
|
533
|
+
if (!filter || await filter(entry)) {
|
|
534
|
+
keptEntries.push(entry);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
await zipReader.close();
|
|
538
|
+
await initStream(zipWriter.writer);
|
|
539
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader;
|
|
540
|
+
keptEntries.forEach(entry => {
|
|
541
|
+
const { filename } = entry;
|
|
542
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
543
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
544
|
+
}
|
|
545
|
+
if (filenames.has(filename)) {
|
|
546
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
547
|
+
}
|
|
548
|
+
filenames.add(filename);
|
|
549
|
+
appendedFilenames.push(filename);
|
|
550
|
+
});
|
|
551
|
+
zipWriter.writerLocked = true;
|
|
552
|
+
const { lockWriter } = zipWriter;
|
|
553
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
554
|
+
zipWriter.writerLocked = false;
|
|
555
|
+
resolve();
|
|
556
|
+
});
|
|
557
|
+
await lockWriter;
|
|
558
|
+
if (zipWriter.addSplitZipSignature) {
|
|
559
|
+
delete zipWriter.addSplitZipSignature;
|
|
560
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
561
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
562
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
566
|
+
keptEntries.forEach(entry => {
|
|
567
|
+
const {
|
|
568
|
+
version,
|
|
569
|
+
rawLastModDate,
|
|
570
|
+
rawFilename,
|
|
571
|
+
rawBitFlag,
|
|
572
|
+
uncompressedSize,
|
|
573
|
+
compressedSize,
|
|
574
|
+
extraFieldZip64
|
|
575
|
+
} = entry;
|
|
576
|
+
let {
|
|
577
|
+
compressionMethod,
|
|
578
|
+
rawExtraField,
|
|
579
|
+
} = entry;
|
|
580
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
581
|
+
if (entry.extraFieldAES) {
|
|
582
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
583
|
+
}
|
|
584
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
585
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
586
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
587
|
+
const {
|
|
588
|
+
headerArray,
|
|
589
|
+
headerView
|
|
590
|
+
} = getHeaderArrayData({
|
|
591
|
+
version,
|
|
592
|
+
bitFlag: rawBitFlag,
|
|
593
|
+
compressionMethod,
|
|
594
|
+
uncompressedSize,
|
|
595
|
+
compressedSize,
|
|
596
|
+
rawLastModDate,
|
|
597
|
+
rawFilename,
|
|
598
|
+
zip64CompressedSize,
|
|
599
|
+
zip64UncompressedSize,
|
|
600
|
+
extraFieldLength
|
|
601
|
+
});
|
|
602
|
+
const { crc32 } = entry;
|
|
603
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
604
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
605
|
+
}
|
|
606
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
607
|
+
Object.assign(entry, {
|
|
608
|
+
zip64Enabled: true,
|
|
609
|
+
zip64UncompressedSize,
|
|
610
|
+
zip64CompressedSize,
|
|
611
|
+
offset,
|
|
612
|
+
diskNumberStart,
|
|
613
|
+
zip64DiskNumberStart: false,
|
|
614
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
615
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
616
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
617
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
618
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
619
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
620
|
+
rawExtraField,
|
|
621
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
622
|
+
headerArray,
|
|
623
|
+
headerView
|
|
624
|
+
});
|
|
625
|
+
fileEntries.set(entry.filename, entry);
|
|
626
|
+
});
|
|
627
|
+
} catch (error) {
|
|
628
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
629
|
+
throw error;
|
|
630
|
+
} finally {
|
|
631
|
+
resolveAppendZip();
|
|
632
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
633
|
+
if (releaseLockWriter) {
|
|
634
|
+
releaseLockWriter();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
630
639
|
async function prependZipEntries(zipWriter, reader) {
|
|
631
640
|
if (zipWriter.filenames.size) {
|
|
632
641
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
633
642
|
}
|
|
634
|
-
await
|
|
643
|
+
await appendZipEntries(zipWriter, reader);
|
|
635
644
|
}
|
|
636
645
|
|
|
637
646
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -2449,26 +2458,63 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
2449
2458
|
return rawExtraField;
|
|
2450
2459
|
}
|
|
2451
2460
|
|
|
2452
|
-
async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
2461
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
2453
2462
|
const { writer } = zipWriter;
|
|
2454
2463
|
const entryPositions = new Map();
|
|
2455
|
-
if (writer.closeDisk) {
|
|
2464
|
+
if (writer.closeDisk || compact) {
|
|
2456
2465
|
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
2457
2466
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2467
|
+
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
2468
|
+
const keptEntrySet = new Set(keptEntries);
|
|
2469
|
+
const localHeaderLengths = new Map();
|
|
2470
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
2471
|
+
const entry = sortedEntries[indexEntry];
|
|
2472
|
+
if (keptEntrySet.has(entry)) {
|
|
2473
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
2474
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
2475
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
2476
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
2477
|
+
}
|
|
2478
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
2479
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
2480
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
2481
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
2482
|
+
}
|
|
2483
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
2484
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
2485
|
+
}
|
|
2486
|
+
regionEnds[indexEntry] = entryEnd;
|
|
2487
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
let copiedOffset = 0;
|
|
2491
|
+
let lastPosition;
|
|
2492
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
2493
|
+
const entry = sortedEntries[indexEntry];
|
|
2494
|
+
if (keptEntrySet.has(entry)) {
|
|
2495
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
2496
|
+
if (sourceOffset < copiedOffset) {
|
|
2497
|
+
entryPositions.set(entry, lastPosition);
|
|
2498
|
+
} else {
|
|
2499
|
+
if (!compact) {
|
|
2500
|
+
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
2501
|
+
}
|
|
2502
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
2503
|
+
await writer.closeDisk();
|
|
2504
|
+
}
|
|
2505
|
+
lastPosition = {
|
|
2506
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
2507
|
+
diskNumberStart: getDiskNumber(writer)
|
|
2508
|
+
};
|
|
2509
|
+
entryPositions.set(entry, lastPosition);
|
|
2510
|
+
await copyData(zipWriter, reader, sourceOffset, regionEnds[indexEntry] - sourceOffset);
|
|
2511
|
+
copiedOffset = regionEnds[indexEntry];
|
|
2512
|
+
}
|
|
2464
2513
|
}
|
|
2465
|
-
entryPositions.set(entry, {
|
|
2466
|
-
offset: getSegmentOffset(zipWriter, writer),
|
|
2467
|
-
diskNumberStart: getDiskNumber(writer)
|
|
2468
|
-
});
|
|
2469
|
-
copiedLength = sourceOffset;
|
|
2470
2514
|
}
|
|
2471
|
-
|
|
2515
|
+
if (!compact) {
|
|
2516
|
+
await copyData(zipWriter, reader, copiedOffset, directoryOffset - copiedOffset);
|
|
2517
|
+
}
|
|
2472
2518
|
} else {
|
|
2473
2519
|
const baseOffset = zipWriter.offset;
|
|
2474
2520
|
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
@@ -2480,6 +2526,20 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
|
2480
2526
|
return entryPositions;
|
|
2481
2527
|
}
|
|
2482
2528
|
|
|
2529
|
+
function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
2530
|
+
const regionEnds = new Array(sortedEntries.length);
|
|
2531
|
+
let regionEnd = directoryOffset;
|
|
2532
|
+
for (let indexEntry = sortedEntries.length - 1; indexEntry >= 0; indexEntry--) {
|
|
2533
|
+
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
2534
|
+
const nextEntry = sortedEntries[indexEntry + 1];
|
|
2535
|
+
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
2536
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
2537
|
+
}
|
|
2538
|
+
regionEnds[indexEntry] = regionEnd;
|
|
2539
|
+
}
|
|
2540
|
+
return regionEnds;
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2483
2543
|
async function copyData(zipWriter, reader, offset, size) {
|
|
2484
2544
|
if (size > 0) {
|
|
2485
2545
|
const { writer } = zipWriter;
|
|
@@ -2487,11 +2547,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
2487
2547
|
try {
|
|
2488
2548
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
2489
2549
|
} catch (error) {
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2550
|
+
if (copiedLength) {
|
|
2551
|
+
zipWriter.hasCorruptedEntries = true;
|
|
2552
|
+
try {
|
|
2553
|
+
error.corruptedEntry = true;
|
|
2554
|
+
} catch {
|
|
2555
|
+
// ignored
|
|
2556
|
+
}
|
|
2495
2557
|
}
|
|
2496
2558
|
throw error;
|
|
2497
2559
|
} finally {
|
|
@@ -2502,11 +2564,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
2502
2564
|
}
|
|
2503
2565
|
|
|
2504
2566
|
async function getLocalHeaderLength(reader, offset) {
|
|
2505
|
-
const headerArray =
|
|
2567
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
2568
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
2569
|
+
EMPTY_UINT8_ARRAY;
|
|
2506
2570
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
2507
|
-
return
|
|
2571
|
+
return UNDEFINED_VALUE;
|
|
2508
2572
|
}
|
|
2509
2573
|
const headerView = getDataView(headerArray);
|
|
2574
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
2575
|
+
return UNDEFINED_VALUE;
|
|
2576
|
+
}
|
|
2510
2577
|
return HEADER_SIZE +
|
|
2511
2578
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
2512
2579
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
package/lib/zip-core-reader.js
CHANGED
|
@@ -68,6 +68,8 @@ export {
|
|
|
68
68
|
WARNING_PREPENDED_DATA,
|
|
69
69
|
WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
70
70
|
WARNING_TRAILING_CENTRAL_DIRECTORY_DATA,
|
|
71
|
+
WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET,
|
|
72
|
+
WARNING_MISSING_ZIP64_EXTRA_FIELD,
|
|
71
73
|
WARNING_DUPLICATE_FILENAME,
|
|
72
74
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
73
75
|
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
package/package.json
CHANGED