single-file-core 1.6.20 → 1.6.22
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/package.json +1 -1
- package/processors/compression/compression.js +17 -1
- package/vendor/css-tree.js +12 -11
- package/vendor/zip/z-worker.js +1 -1
- package/vendor/zip/zip.js +867 -477
- package/vendor/zip/zip.min.js +1 -1
package/vendor/zip/zip.js
CHANGED
|
@@ -119,6 +119,10 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
119
119
|
|
|
120
120
|
const UNDEFINED_VALUE = undefined;
|
|
121
121
|
const INFINITY_VALUE = Infinity;
|
|
122
|
+
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
123
|
+
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
124
|
+
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
125
|
+
|
|
122
126
|
const UNDEFINED_TYPE = "undefined";
|
|
123
127
|
const FUNCTION_TYPE = "function";
|
|
124
128
|
const OBJECT_TYPE = "object";
|
|
@@ -178,7 +182,6 @@ const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
|
178
182
|
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
179
183
|
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
180
184
|
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
181
|
-
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
182
185
|
const OPTION_PREVENT_CLOSE = "preventClose";
|
|
183
186
|
const OPTION_ENCRYPTION_STRENGTH = "encryptionStrength";
|
|
184
187
|
const OPTION_EXTENDED_TIMESTAMP = "extendedTimestamp";
|
|
@@ -215,6 +218,7 @@ const ERR_INVALID_FUNCTION_OPTION = "Invalid option (must be a function)";
|
|
|
215
218
|
const ERR_INVALID_SIGNAL = "Invalid signal (must be an AbortSignal instance)";
|
|
216
219
|
const ERR_INVALID_PASSWORD_TYPE = "Invalid password (password must be a string, rawPassword must be a Uint8Array)";
|
|
217
220
|
const ERR_INVALID_PASS_THROUGH_VALUE = "Invalid passThrough option (must be a boolean or 'compressed')";
|
|
221
|
+
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
218
222
|
const ERR_ABORTED = "The operation was aborted";
|
|
219
223
|
const ABORT_ERROR_NAME = "AbortError";
|
|
220
224
|
|
|
@@ -225,6 +229,13 @@ function checkFunctionOption(value) {
|
|
|
225
229
|
return value;
|
|
226
230
|
}
|
|
227
231
|
|
|
232
|
+
function checkReaderOptionsObject(readerOptions) {
|
|
233
|
+
if (readerOptions && (typeof readerOptions != OBJECT_TYPE || Array.isArray(readerOptions))) {
|
|
234
|
+
throw new Error(ERR_INVALID_READER_OPTIONS);
|
|
235
|
+
}
|
|
236
|
+
return readerOptions;
|
|
237
|
+
}
|
|
238
|
+
|
|
228
239
|
function checkSignalOption(signal) {
|
|
229
240
|
if (signal && (typeof signal.addEventListener != FUNCTION_TYPE || typeof signal.aborted != BOOLEAN_TYPE)) {
|
|
230
241
|
throw new Error(ERR_INVALID_SIGNAL);
|
|
@@ -296,7 +307,7 @@ function toNumber(value) {
|
|
|
296
307
|
*/
|
|
297
308
|
|
|
298
309
|
|
|
299
|
-
const DEFAULT_CHUNK_SIZE$1 =
|
|
310
|
+
const DEFAULT_CHUNK_SIZE$1 = 256 * 1024;
|
|
300
311
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
301
312
|
const MINIMUM_PROPERTY_VALUE = 1;
|
|
302
313
|
const ERR_INVALID_MAX_WORKERS = "Invalid maxWorkers (must be an integer greater than 0)";
|
|
@@ -320,7 +331,6 @@ const DEFAULT_CONFIGURATION = {
|
|
|
320
331
|
workerStartupTimeout: 5000,
|
|
321
332
|
useWebWorkers: true,
|
|
322
333
|
useCompressionStream: true,
|
|
323
|
-
transferStreams: true,
|
|
324
334
|
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
325
335
|
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
326
336
|
};
|
|
@@ -334,8 +344,7 @@ const URI_PROPERTY_NAMES = [
|
|
|
334
344
|
];
|
|
335
345
|
const BOOLEAN_PROPERTY_NAMES = [
|
|
336
346
|
"useCompressionStream",
|
|
337
|
-
"useWebWorkers"
|
|
338
|
-
"transferStreams"
|
|
347
|
+
"useWebWorkers"
|
|
339
348
|
];
|
|
340
349
|
const NUMBER_PROPERTY_NAMES = [
|
|
341
350
|
"chunkSize",
|
|
@@ -1276,12 +1285,12 @@ let createEngine = createEngine$1;
|
|
|
1276
1285
|
class AESDecryptionStream extends TransformStream {
|
|
1277
1286
|
|
|
1278
1287
|
constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly, checkAuthenticationCode = true }) {
|
|
1288
|
+
const aesCrypto = {};
|
|
1279
1289
|
super({
|
|
1280
1290
|
start() {
|
|
1281
|
-
initAesCrypto(
|
|
1291
|
+
initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength);
|
|
1282
1292
|
},
|
|
1283
1293
|
async transform(chunk, controller) {
|
|
1284
|
-
const aesCrypto = this;
|
|
1285
1294
|
const {
|
|
1286
1295
|
password,
|
|
1287
1296
|
strength,
|
|
@@ -1300,6 +1309,9 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1300
1309
|
} else {
|
|
1301
1310
|
await ready;
|
|
1302
1311
|
}
|
|
1312
|
+
if (aesCrypto.discarded) {
|
|
1313
|
+
return;
|
|
1314
|
+
}
|
|
1303
1315
|
const output = new Uint8Array(chunk.length - AUTHENTICATION_CODE_LENGTH - ((chunk.length - AUTHENTICATION_CODE_LENGTH) % BLOCK_LENGTH));
|
|
1304
1316
|
controller.enqueue(append(aesCrypto, chunk, output, 0, AUTHENTICATION_CODE_LENGTH, true));
|
|
1305
1317
|
},
|
|
@@ -1308,9 +1320,12 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1308
1320
|
engine,
|
|
1309
1321
|
pendingInput,
|
|
1310
1322
|
ready
|
|
1311
|
-
} =
|
|
1323
|
+
} = aesCrypto;
|
|
1312
1324
|
if (engine) {
|
|
1313
1325
|
await ready;
|
|
1326
|
+
if (aesCrypto.discarded) {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1314
1329
|
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1315
1330
|
const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
|
|
1316
1331
|
engine.process(decryptedChunkArray, true);
|
|
@@ -1320,27 +1335,26 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1320
1335
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
1321
1336
|
}
|
|
1322
1337
|
if (invalidAuthenticationCode && checkAuthenticationCode) {
|
|
1323
|
-
|
|
1338
|
+
controller.error(new Error(ERR_INVALID_AUTHENTICATION_CODE));
|
|
1339
|
+
return;
|
|
1324
1340
|
}
|
|
1325
1341
|
controller.enqueue(decryptedChunkArray);
|
|
1326
1342
|
}
|
|
1327
|
-
},
|
|
1328
|
-
cancel() {
|
|
1329
|
-
disposeEngine(this);
|
|
1330
1343
|
}
|
|
1331
1344
|
});
|
|
1345
|
+
setDisposingReadable(this, aesCrypto);
|
|
1332
1346
|
}
|
|
1333
1347
|
}
|
|
1334
1348
|
|
|
1335
1349
|
class AESEncryptionStream extends TransformStream {
|
|
1336
1350
|
|
|
1337
1351
|
constructor({ password, rawPassword, encryptionStrength }) {
|
|
1352
|
+
const aesCrypto = {};
|
|
1338
1353
|
super({
|
|
1339
1354
|
start() {
|
|
1340
|
-
initAesCrypto(
|
|
1355
|
+
initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength);
|
|
1341
1356
|
},
|
|
1342
1357
|
async transform(chunk, controller) {
|
|
1343
|
-
const aesCrypto = this;
|
|
1344
1358
|
const {
|
|
1345
1359
|
password,
|
|
1346
1360
|
strength,
|
|
@@ -1354,6 +1368,9 @@ class AESEncryptionStream extends TransformStream {
|
|
|
1354
1368
|
} else {
|
|
1355
1369
|
await ready;
|
|
1356
1370
|
}
|
|
1371
|
+
if (aesCrypto.discarded) {
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1357
1374
|
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
1358
1375
|
output.set(preamble, 0);
|
|
1359
1376
|
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
|
|
@@ -1363,19 +1380,20 @@ class AESEncryptionStream extends TransformStream {
|
|
|
1363
1380
|
engine,
|
|
1364
1381
|
pendingInput,
|
|
1365
1382
|
ready
|
|
1366
|
-
} =
|
|
1383
|
+
} = aesCrypto;
|
|
1367
1384
|
if (engine) {
|
|
1368
1385
|
await ready;
|
|
1386
|
+
if (aesCrypto.discarded) {
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1369
1389
|
const encryptedChunkArray = new Uint8Array(pendingInput);
|
|
1370
1390
|
engine.process(encryptedChunkArray, false);
|
|
1371
1391
|
const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1372
1392
|
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1373
1393
|
}
|
|
1374
|
-
},
|
|
1375
|
-
cancel() {
|
|
1376
|
-
disposeEngine(this);
|
|
1377
1394
|
}
|
|
1378
1395
|
});
|
|
1396
|
+
setDisposingReadable(this, aesCrypto);
|
|
1379
1397
|
}
|
|
1380
1398
|
}
|
|
1381
1399
|
|
|
@@ -1384,7 +1402,37 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
|
|
|
1384
1402
|
ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
|
|
1385
1403
|
password: encodePassword(password, rawPassword),
|
|
1386
1404
|
strength: encryptionStrength - 1,
|
|
1387
|
-
pendingInput: EMPTY_UINT8_ARRAY
|
|
1405
|
+
pendingInput: EMPTY_UINT8_ARRAY,
|
|
1406
|
+
discarded: false
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function setDisposingReadable(stream, aesCrypto) {
|
|
1411
|
+
const reader = stream.readable.getReader();
|
|
1412
|
+
const readable = new ReadableStream({
|
|
1413
|
+
async pull(controller) {
|
|
1414
|
+
try {
|
|
1415
|
+
const { value, done } = await reader.read();
|
|
1416
|
+
if (done) {
|
|
1417
|
+
controller.close();
|
|
1418
|
+
} else {
|
|
1419
|
+
controller.enqueue(value);
|
|
1420
|
+
}
|
|
1421
|
+
} catch (error) {
|
|
1422
|
+
disposeEngine(aesCrypto);
|
|
1423
|
+
reader.cancel(error).catch(() => { });
|
|
1424
|
+
throw error;
|
|
1425
|
+
}
|
|
1426
|
+
},
|
|
1427
|
+
cancel(reason) {
|
|
1428
|
+
disposeEngine(aesCrypto);
|
|
1429
|
+
return reader.cancel(reason);
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
Object.defineProperty(stream, "readable", {
|
|
1433
|
+
get() {
|
|
1434
|
+
return readable;
|
|
1435
|
+
}
|
|
1388
1436
|
});
|
|
1389
1437
|
}
|
|
1390
1438
|
|
|
@@ -1417,7 +1465,9 @@ async function createDecryptionKeys(decrypt, strength, password, preamble) {
|
|
|
1417
1465
|
}
|
|
1418
1466
|
}
|
|
1419
1467
|
|
|
1420
|
-
function disposeEngine(
|
|
1468
|
+
function disposeEngine(aesCrypto) {
|
|
1469
|
+
const { engine } = aesCrypto;
|
|
1470
|
+
aesCrypto.discarded = true;
|
|
1421
1471
|
if (engine && engine.dispose) {
|
|
1422
1472
|
engine.dispose();
|
|
1423
1473
|
}
|
|
@@ -1434,6 +1484,9 @@ async function createKeys$1(aesCrypto, strength, password, salt) {
|
|
|
1434
1484
|
const keyLength = KEY_LENGTH[strength];
|
|
1435
1485
|
const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
|
|
1436
1486
|
aesCrypto.engine = createEngine(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
|
|
1487
|
+
if (aesCrypto.discarded) {
|
|
1488
|
+
disposeEngine(aesCrypto);
|
|
1489
|
+
}
|
|
1437
1490
|
return subarray(compositeKey, keyLength * 2);
|
|
1438
1491
|
}
|
|
1439
1492
|
|
|
@@ -1585,11 +1638,11 @@ function encrypt(target, input) {
|
|
|
1585
1638
|
}
|
|
1586
1639
|
|
|
1587
1640
|
function createKeys(target, password, rawPassword) {
|
|
1588
|
-
const
|
|
1641
|
+
const cryptoKeys = [0x12345678, 0x23456789, 0x34567890];
|
|
1589
1642
|
Object.assign(target, {
|
|
1590
|
-
|
|
1591
|
-
crcKey0: new Crc32(
|
|
1592
|
-
crcKey2: new Crc32(
|
|
1643
|
+
cryptoKeys,
|
|
1644
|
+
crcKey0: new Crc32(cryptoKeys[0]),
|
|
1645
|
+
crcKey2: new Crc32(cryptoKeys[2])
|
|
1593
1646
|
});
|
|
1594
1647
|
if (rawPassword) {
|
|
1595
1648
|
for (let index = 0; index < rawPassword.length; index++) {
|
|
@@ -1603,17 +1656,17 @@ function createKeys(target, password, rawPassword) {
|
|
|
1603
1656
|
}
|
|
1604
1657
|
|
|
1605
1658
|
function updateKeys(target, byte) {
|
|
1606
|
-
let [, key1] = target.
|
|
1659
|
+
let [, key1] = target.cryptoKeys;
|
|
1607
1660
|
target.crcKey0.append([byte]);
|
|
1608
1661
|
const key0 = ~target.crcKey0.get();
|
|
1609
1662
|
key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1);
|
|
1610
1663
|
target.crcKey2.append([key1 >>> 24]);
|
|
1611
1664
|
const key2 = ~target.crcKey2.get();
|
|
1612
|
-
target.
|
|
1665
|
+
target.cryptoKeys = [key0, key1, key2];
|
|
1613
1666
|
}
|
|
1614
1667
|
|
|
1615
1668
|
function getByte(target) {
|
|
1616
|
-
const temp = target.
|
|
1669
|
+
const temp = target.cryptoKeys[2] | 2;
|
|
1617
1670
|
return getInt8(Math.imul(temp, (temp ^ 1)) >>> 8);
|
|
1618
1671
|
}
|
|
1619
1672
|
|
|
@@ -1661,11 +1714,16 @@ function toCompatibleReadable(readable) {
|
|
|
1661
1714
|
const reader = readable.getReader();
|
|
1662
1715
|
return new ReadableStream({
|
|
1663
1716
|
async pull(controller) {
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1717
|
+
try {
|
|
1718
|
+
const { value, done } = await reader.read();
|
|
1719
|
+
if (done) {
|
|
1720
|
+
controller.close();
|
|
1721
|
+
} else {
|
|
1722
|
+
controller.enqueue(value);
|
|
1723
|
+
}
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
reader.cancel(error).catch(() => { });
|
|
1726
|
+
throw error;
|
|
1669
1727
|
}
|
|
1670
1728
|
},
|
|
1671
1729
|
cancel(reason) {
|
|
@@ -1844,14 +1902,15 @@ async function ensureCodecStreams(format, codecURI) {
|
|
|
1844
1902
|
|
|
1845
1903
|
const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
|
|
1846
1904
|
const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
|
|
1905
|
+
const ERR_CODEC_OUT_OF_MEMORY = "Codec out of memory";
|
|
1847
1906
|
const ERR_INVALID_CRC32 = "Invalid CRC32";
|
|
1907
|
+
const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
|
|
1848
1908
|
const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
1849
1909
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
1850
1910
|
const FORMAT_GZIP = "gzip";
|
|
1851
1911
|
const GZIP_HEADER_LENGTH = 10;
|
|
1852
1912
|
const GZIP_TRAILER_LENGTH = 8;
|
|
1853
1913
|
const GZIP_HEADER_BYTES = [0x1f, 0x8b, 0x08];
|
|
1854
|
-
const GZIP_OUTPUT_STALL_TIMEOUT = 5000;
|
|
1855
1914
|
|
|
1856
1915
|
class DeflateStream extends TransformStream {
|
|
1857
1916
|
|
|
@@ -1862,7 +1921,7 @@ class DeflateStream extends TransformStream {
|
|
|
1862
1921
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
1863
1922
|
let readable = super.readable;
|
|
1864
1923
|
const codecStreams = format && getCodecStreams(format);
|
|
1865
|
-
const GzipCompressionStream =
|
|
1924
|
+
const GzipCompressionStream = getGzipCodecStream(useCompressionStream, CompressionStream, CompressionStreamFallback);
|
|
1866
1925
|
const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) && Boolean(GzipCompressionStream);
|
|
1867
1926
|
if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
|
|
1868
1927
|
crc32Stream = new Crc32Stream();
|
|
@@ -1879,11 +1938,14 @@ class DeflateStream extends TransformStream {
|
|
|
1879
1938
|
try {
|
|
1880
1939
|
readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
|
|
1881
1940
|
} catch (error) {
|
|
1941
|
+
if (!useCompressionStream && CompressionStreamFallback) {
|
|
1942
|
+
throw mapMemoryError(error);
|
|
1943
|
+
}
|
|
1882
1944
|
let gzipStream;
|
|
1883
1945
|
try {
|
|
1884
1946
|
gzipStream = new CompressionStream(FORMAT_GZIP);
|
|
1885
1947
|
} catch {
|
|
1886
|
-
throw error;
|
|
1948
|
+
throw mapMemoryError(error);
|
|
1887
1949
|
}
|
|
1888
1950
|
readable = pipeThroughBackpressured(readable, gzipStream);
|
|
1889
1951
|
readable = pipeThrough(readable, new GzipToRawDeflateStream());
|
|
@@ -1947,72 +2009,123 @@ class GzipToRawDeflateStream extends TransformStream {
|
|
|
1947
2009
|
}
|
|
1948
2010
|
}
|
|
1949
2011
|
|
|
1950
|
-
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
|
|
2012
|
+
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors) {
|
|
2013
|
+
const writer = gzipStream.writable.getWriter();
|
|
2014
|
+
const reader = gzipStream.readable.getReader();
|
|
2015
|
+
const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
|
|
1951
2016
|
let outputLength = 0;
|
|
1952
|
-
let
|
|
1953
|
-
let
|
|
1954
|
-
let
|
|
1955
|
-
const
|
|
1956
|
-
|
|
1957
|
-
|
|
2017
|
+
let trailerWritten = false;
|
|
2018
|
+
let settled = false;
|
|
2019
|
+
let resolvePull, controller;
|
|
2020
|
+
const output = new ReadableStream({
|
|
2021
|
+
start(streamController) {
|
|
2022
|
+
controller = streamController;
|
|
2023
|
+
},
|
|
2024
|
+
pull() {
|
|
2025
|
+
resumePump();
|
|
2026
|
+
},
|
|
2027
|
+
cancel(reason) {
|
|
2028
|
+
settled = true;
|
|
2029
|
+
resumePump();
|
|
2030
|
+
return reader.cancel(reason);
|
|
2031
|
+
}
|
|
1958
2032
|
});
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2033
|
+
pump();
|
|
2034
|
+
drain();
|
|
2035
|
+
return output;
|
|
2036
|
+
|
|
2037
|
+
async function pump() {
|
|
2038
|
+
const inputReader = readable.getReader();
|
|
2039
|
+
try {
|
|
1965
2040
|
const header = new Uint8Array(GZIP_HEADER_LENGTH);
|
|
1966
2041
|
header.set(GZIP_HEADER_BYTES);
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2042
|
+
await writer.write(header);
|
|
2043
|
+
for (; ;) {
|
|
2044
|
+
await outputCapacity();
|
|
2045
|
+
await writer.ready;
|
|
2046
|
+
const { value, done } = await readSource(inputReader, sourceErrors);
|
|
2047
|
+
if (done) {
|
|
2048
|
+
break;
|
|
2049
|
+
}
|
|
2050
|
+
await writer.write(value);
|
|
2051
|
+
}
|
|
2052
|
+
if (outputCrc32) {
|
|
2053
|
+
await writer.write(new Uint8Array(0));
|
|
1979
2054
|
}
|
|
1980
2055
|
const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
|
|
1981
2056
|
const dataView = getDataView(trailer);
|
|
1982
|
-
dataView.setUint32(0,
|
|
2057
|
+
dataView.setUint32(0, outputCrc32 ? outputCrc32.get() : crc32, true);
|
|
1983
2058
|
dataView.setUint32(4, outputSize, true);
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2059
|
+
trailerWritten = true;
|
|
2060
|
+
await writer.write(trailer);
|
|
2061
|
+
await writer.close();
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
await abort(writer, error);
|
|
2064
|
+
await cancel(inputReader, error);
|
|
1988
2065
|
}
|
|
1989
|
-
}
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
async function drain() {
|
|
2069
|
+
try {
|
|
2070
|
+
for (; ;) {
|
|
2071
|
+
const { value, done } = await read();
|
|
2072
|
+
if (done) {
|
|
2073
|
+
break;
|
|
2074
|
+
}
|
|
2075
|
+
outputLength += value.length;
|
|
2076
|
+
if (outputLength > outputSize) {
|
|
2077
|
+
throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
2078
|
+
}
|
|
2079
|
+
if (outputCrc32) {
|
|
2080
|
+
outputCrc32.append(value);
|
|
2081
|
+
}
|
|
2082
|
+
controller.enqueue(value);
|
|
1998
2083
|
}
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2084
|
+
if (!settled) {
|
|
2085
|
+
settled = true;
|
|
2086
|
+
controller.close();
|
|
2087
|
+
}
|
|
2088
|
+
} catch (error) {
|
|
2089
|
+
fail(error);
|
|
2090
|
+
await cancel(reader, error);
|
|
2003
2091
|
}
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
function read() {
|
|
2095
|
+
return reader.read().catch(error => {
|
|
2096
|
+
if (trailerWritten) {
|
|
2097
|
+
if (!outputCrc32) {
|
|
2098
|
+
throw mapError(error, ERR_INVALID_CRC32);
|
|
2099
|
+
}
|
|
2100
|
+
if (outputLength != outputSize) {
|
|
2101
|
+
throw mapError(error, ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
2102
|
+
}
|
|
2103
|
+
return { done: true };
|
|
2104
|
+
}
|
|
2105
|
+
throw mapCodecError(error, sourceErrors);
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2008
2108
|
|
|
2009
|
-
function
|
|
2010
|
-
|
|
2011
|
-
|
|
2109
|
+
function outputCapacity() {
|
|
2110
|
+
if (!settled && controller.desiredSize <= 0) {
|
|
2111
|
+
return new Promise(resolve => resolvePull = resolve);
|
|
2112
|
+
}
|
|
2012
2113
|
}
|
|
2013
2114
|
|
|
2014
|
-
function
|
|
2015
|
-
|
|
2115
|
+
function resumePump() {
|
|
2116
|
+
if (resolvePull) {
|
|
2117
|
+
const resolve = resolvePull;
|
|
2118
|
+
resolvePull = UNDEFINED_VALUE;
|
|
2119
|
+
resolve();
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
function fail(error) {
|
|
2124
|
+
if (!settled) {
|
|
2125
|
+
settled = true;
|
|
2126
|
+
controller.error(error);
|
|
2127
|
+
resumePump();
|
|
2128
|
+
}
|
|
2016
2129
|
}
|
|
2017
2130
|
}
|
|
2018
2131
|
|
|
@@ -2032,35 +2145,49 @@ class InflateStream extends TransformStream {
|
|
|
2032
2145
|
}
|
|
2033
2146
|
}
|
|
2034
2147
|
if (compressed) {
|
|
2148
|
+
const sourceErrors = new Set();
|
|
2035
2149
|
const codecStreams = format && getCodecStreams(format);
|
|
2150
|
+
let gzipStream;
|
|
2036
2151
|
if (codecStreams) {
|
|
2037
|
-
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
|
|
2152
|
+
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }), sourceErrors);
|
|
2038
2153
|
} else {
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
} catch (error) {
|
|
2042
|
-
if (deflate64 || outputSize === UNDEFINED_VALUE) {
|
|
2043
|
-
throw error;
|
|
2044
|
-
}
|
|
2045
|
-
let gzipStream;
|
|
2154
|
+
const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
|
|
2155
|
+
if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
|
|
2046
2156
|
try {
|
|
2047
|
-
gzipStream = new
|
|
2157
|
+
gzipStream = new GzipDecompressionStream(FORMAT_GZIP, { chunkSize });
|
|
2048
2158
|
} catch {
|
|
2049
|
-
|
|
2159
|
+
gzipStream = UNDEFINED_VALUE;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
if (!gzipStream) {
|
|
2163
|
+
try {
|
|
2164
|
+
readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback, sourceErrors);
|
|
2165
|
+
} catch (error) {
|
|
2166
|
+
if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
|
|
2167
|
+
throw mapMemoryError(error);
|
|
2168
|
+
}
|
|
2169
|
+
try {
|
|
2170
|
+
gzipStream = new DecompressionStream(FORMAT_GZIP);
|
|
2171
|
+
} catch {
|
|
2172
|
+
throw mapMemoryError(error);
|
|
2173
|
+
}
|
|
2050
2174
|
}
|
|
2051
|
-
gzipCrc32 = new Crc32();
|
|
2052
|
-
readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, gzipCrc32);
|
|
2053
2175
|
}
|
|
2054
2176
|
}
|
|
2055
|
-
|
|
2177
|
+
if (gzipStream) {
|
|
2178
|
+
gzipCrc32 = true;
|
|
2179
|
+
readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors);
|
|
2180
|
+
} else {
|
|
2181
|
+
readable = mapInflateStreamError(readable, sourceErrors);
|
|
2182
|
+
}
|
|
2056
2183
|
}
|
|
2057
2184
|
if (checkCrc32 && !gzipCrc32) {
|
|
2058
2185
|
crc32Stream = new Crc32Stream();
|
|
2059
2186
|
readable = pipeThrough(readable, crc32Stream);
|
|
2060
2187
|
}
|
|
2061
2188
|
setReadable(this, readable, () => {
|
|
2062
|
-
if (
|
|
2063
|
-
const computedCrc32 =
|
|
2189
|
+
if (crc32Stream) {
|
|
2190
|
+
const computedCrc32 = new DataView(crc32Stream.value.buffer).getUint32(0, false);
|
|
2064
2191
|
if (crc32 != computedCrc32) {
|
|
2065
2192
|
throw new Error(ERR_INVALID_CRC32);
|
|
2066
2193
|
}
|
|
@@ -2117,15 +2244,15 @@ function createCodecStream(CodecStreamClass, format, options) {
|
|
|
2117
2244
|
return new CodecStreamClass(format, options);
|
|
2118
2245
|
}
|
|
2119
2246
|
|
|
2120
|
-
function
|
|
2121
|
-
if (useCompressionStream &&
|
|
2122
|
-
return
|
|
2123
|
-
} else if (
|
|
2124
|
-
return
|
|
2247
|
+
function getGzipCodecStream(useCompressionStream, CodecStreamNative, CodecStreamFallback) {
|
|
2248
|
+
if (useCompressionStream && CodecStreamNative) {
|
|
2249
|
+
return CodecStreamNative;
|
|
2250
|
+
} else if (CodecStreamFallback && CodecStreamFallback.requiresModule) {
|
|
2251
|
+
return CodecStreamFallback;
|
|
2125
2252
|
}
|
|
2126
2253
|
}
|
|
2127
2254
|
|
|
2128
|
-
function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
|
|
2255
|
+
function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback, sourceErrors) {
|
|
2129
2256
|
const Stream = useCompressionStream && CompressionStreamNative ?
|
|
2130
2257
|
CompressionStreamNative :
|
|
2131
2258
|
CompressionStreamFallback || CompressionStreamNative;
|
|
@@ -2140,14 +2267,14 @@ function pipeThroughCompressionStream(readable, useCompressionStream, options, C
|
|
|
2140
2267
|
throw error;
|
|
2141
2268
|
}
|
|
2142
2269
|
}
|
|
2143
|
-
return pipeThroughBackpressured(readable, codecStream);
|
|
2270
|
+
return pipeThroughBackpressured(readable, codecStream, sourceErrors);
|
|
2144
2271
|
}
|
|
2145
2272
|
|
|
2146
2273
|
function pipeThrough(readable, transformStream) {
|
|
2147
2274
|
return toCompatibleReadable(readable).pipeThrough(transformStream);
|
|
2148
2275
|
}
|
|
2149
2276
|
|
|
2150
|
-
function pipeThroughBackpressured(readable, transformStream) {
|
|
2277
|
+
function pipeThroughBackpressured(readable, transformStream, sourceErrors) {
|
|
2151
2278
|
const writer = transformStream.writable.getWriter();
|
|
2152
2279
|
const reader = readable.getReader();
|
|
2153
2280
|
pump();
|
|
@@ -2157,7 +2284,7 @@ function pipeThroughBackpressured(readable, transformStream) {
|
|
|
2157
2284
|
try {
|
|
2158
2285
|
for (; ;) {
|
|
2159
2286
|
await writer.ready;
|
|
2160
|
-
const result = await reader
|
|
2287
|
+
const result = await readSource(reader, sourceErrors);
|
|
2161
2288
|
if (result.done) {
|
|
2162
2289
|
await writer.close();
|
|
2163
2290
|
break;
|
|
@@ -2187,26 +2314,49 @@ async function cancel(reader, error) {
|
|
|
2187
2314
|
}
|
|
2188
2315
|
}
|
|
2189
2316
|
|
|
2190
|
-
function
|
|
2317
|
+
function readSource(reader, sourceErrors) {
|
|
2318
|
+
const result = reader.read();
|
|
2319
|
+
return sourceErrors ? result.catch(error => {
|
|
2320
|
+
sourceErrors.add(error);
|
|
2321
|
+
throw error;
|
|
2322
|
+
}) : result;
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
function mapCodecError(error, sourceErrors) {
|
|
2326
|
+
if (sourceErrors.has(error)) {
|
|
2327
|
+
return error;
|
|
2328
|
+
}
|
|
2329
|
+
return mapError(error, isMemoryError(error) ? ERR_CODEC_OUT_OF_MEMORY : ERR_INVALID_COMPRESSED_DATA);
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
function mapMemoryError(error) {
|
|
2333
|
+
return isMemoryError(error) ? mapError(error, ERR_CODEC_OUT_OF_MEMORY) : error;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
function isMemoryError(error) {
|
|
2337
|
+
return isErrorObject(error) && error.code == Z_MEM_ERROR_CODE;
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
function mapError(error, message) {
|
|
2341
|
+
const mappedError = new Error(message);
|
|
2342
|
+
mappedError.cause = error;
|
|
2343
|
+
return mappedError;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
function mapInflateStreamError(readable, sourceErrors) {
|
|
2191
2347
|
const reader = readable.getReader();
|
|
2192
2348
|
return new ReadableStream({
|
|
2193
2349
|
async pull(controller) {
|
|
2194
|
-
let result;
|
|
2195
2350
|
try {
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2351
|
+
const { value, done } = await reader.read();
|
|
2352
|
+
if (done) {
|
|
2353
|
+
controller.close();
|
|
2354
|
+
} else {
|
|
2355
|
+
controller.enqueue(value);
|
|
2200
2356
|
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
throw
|
|
2204
|
-
}
|
|
2205
|
-
const { value, done } = result;
|
|
2206
|
-
if (done) {
|
|
2207
|
-
controller.close();
|
|
2208
|
-
} else {
|
|
2209
|
-
controller.enqueue(value);
|
|
2357
|
+
} catch (error) {
|
|
2358
|
+
await cancel(reader, error);
|
|
2359
|
+
throw mapCodecError(error, sourceErrors);
|
|
2210
2360
|
}
|
|
2211
2361
|
},
|
|
2212
2362
|
cancel(reason) {
|
|
@@ -2244,7 +2394,7 @@ function mapInflateStreamError(readable) {
|
|
|
2244
2394
|
*/
|
|
2245
2395
|
|
|
2246
2396
|
|
|
2247
|
-
const DEFAULT_CHUNK_SIZE =
|
|
2397
|
+
const DEFAULT_CHUNK_SIZE = 256 * 1024;
|
|
2248
2398
|
const MESSAGE_EVENT_TYPE = "message";
|
|
2249
2399
|
const MESSAGE_START = "start";
|
|
2250
2400
|
const MESSAGE_PULL = "pull";
|
|
@@ -2450,7 +2600,7 @@ function disableWebWorker(workerData) {
|
|
|
2450
2600
|
class CodecWorker {
|
|
2451
2601
|
|
|
2452
2602
|
constructor(workerData, { readable, writable }, workerOptions, onTaskFinished) {
|
|
2453
|
-
const { options, config, streamOptions, useWebWorkers,
|
|
2603
|
+
const { options, config, streamOptions, useWebWorkers, workerURI } = workerOptions;
|
|
2454
2604
|
let { createWorker } = workerOptions;
|
|
2455
2605
|
const { signal } = streamOptions;
|
|
2456
2606
|
if (createWorkerFailed) {
|
|
@@ -2467,7 +2617,6 @@ class CodecWorker {
|
|
|
2467
2617
|
workerOptions,
|
|
2468
2618
|
workerURI,
|
|
2469
2619
|
createWorker,
|
|
2470
|
-
transferStreams,
|
|
2471
2620
|
terminate() {
|
|
2472
2621
|
return new Promise(resolve => {
|
|
2473
2622
|
const { worker, busy } = workerData;
|
|
@@ -2570,10 +2719,11 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
|
|
|
2570
2719
|
}
|
|
2571
2720
|
codecStream = new CodecStream(options, config);
|
|
2572
2721
|
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2722
|
+
const { signal } = workerOptions.streamOptions;
|
|
2573
2723
|
await readable
|
|
2574
2724
|
.pipeThrough(codecStream)
|
|
2575
2725
|
.pipeThrough(chunkStream)
|
|
2576
|
-
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2726
|
+
.pipeTo(writable, { preventClose: true, preventAbort: true, signal });
|
|
2577
2727
|
const {
|
|
2578
2728
|
crc32,
|
|
2579
2729
|
inputSize,
|
|
@@ -2641,14 +2791,9 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
|
|
|
2641
2791
|
const MODULE_WORKER_OPTIONS = { type: "module" };
|
|
2642
2792
|
const ERROR_EVENT_TYPE = "error";
|
|
2643
2793
|
const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
|
|
2794
|
+
const ABORT_EVENT_TYPE = "abort";
|
|
2644
2795
|
|
|
2645
2796
|
let webWorkerSource, webWorkerURI, webWorkerOptions;
|
|
2646
|
-
let transferStreamsSupported = true;
|
|
2647
|
-
try {
|
|
2648
|
-
transferStreamsSupported = typeof structuredClone == FUNCTION_TYPE && structuredClone(new DOMException("", "AbortError")).code !== UNDEFINED_VALUE;
|
|
2649
|
-
} catch {
|
|
2650
|
-
// ignored
|
|
2651
|
-
}
|
|
2652
2797
|
|
|
2653
2798
|
setWebWorkerBackend(createWebWorkerInterface);
|
|
2654
2799
|
|
|
@@ -2735,14 +2880,11 @@ async function runWebWorker(workerData, config) {
|
|
|
2735
2880
|
});
|
|
2736
2881
|
const { readable, options } = workerData;
|
|
2737
2882
|
const { writable, closed, abortPipe } = watchClosedStream(workerData.writable, workerData);
|
|
2738
|
-
let streamsTransferred;
|
|
2739
2883
|
try {
|
|
2740
|
-
|
|
2884
|
+
sendMessage({
|
|
2741
2885
|
type: MESSAGE_START,
|
|
2742
2886
|
options,
|
|
2743
|
-
config
|
|
2744
|
-
readable,
|
|
2745
|
-
writable
|
|
2887
|
+
config
|
|
2746
2888
|
}, workerData);
|
|
2747
2889
|
} catch (error) {
|
|
2748
2890
|
abortPipe();
|
|
@@ -2754,12 +2896,10 @@ async function runWebWorker(workerData, config) {
|
|
|
2754
2896
|
workerData.onTaskFinished();
|
|
2755
2897
|
throw error;
|
|
2756
2898
|
}
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
});
|
|
2762
|
-
}
|
|
2899
|
+
Object.assign(workerData, {
|
|
2900
|
+
reader: readable.getReader(),
|
|
2901
|
+
writer: writable.getWriter()
|
|
2902
|
+
});
|
|
2763
2903
|
const { workerStartupTimeout } = config;
|
|
2764
2904
|
if (!workerData.workerAlive && Number.isFinite(workerStartupTimeout) && workerStartupTimeout >= 0) {
|
|
2765
2905
|
workerData.startupTimeout = setTimeout(() => onStartupTimeout(workerData), workerStartupTimeout);
|
|
@@ -2792,7 +2932,7 @@ async function runWebWorker(workerData, config) {
|
|
|
2792
2932
|
}
|
|
2793
2933
|
|
|
2794
2934
|
async function closeWritable() {
|
|
2795
|
-
if (!
|
|
2935
|
+
if (!writable.locked) {
|
|
2796
2936
|
try {
|
|
2797
2937
|
await writable.getWriter().close();
|
|
2798
2938
|
} catch {
|
|
@@ -2817,6 +2957,13 @@ function watchClosedStream(writableSource, workerData) {
|
|
|
2817
2957
|
Object.assign(workerData, { destinationFailed: true, destinationError: error });
|
|
2818
2958
|
}
|
|
2819
2959
|
});
|
|
2960
|
+
const { signal } = workerData.workerOptions.streamOptions;
|
|
2961
|
+
if (signal) {
|
|
2962
|
+
const onAbort = () => abortController.abort(signal.reason);
|
|
2963
|
+
const removeAbortListener = () => signal.removeEventListener(ABORT_EVENT_TYPE, onAbort);
|
|
2964
|
+
signal.addEventListener(ABORT_EVENT_TYPE, onAbort);
|
|
2965
|
+
closed.then(removeAbortListener, removeAbortListener);
|
|
2966
|
+
}
|
|
2820
2967
|
return {
|
|
2821
2968
|
writable, closed, abortPipe: () => {
|
|
2822
2969
|
aborting = true;
|
|
@@ -2976,31 +3123,14 @@ function onWorkerError(event, workerData) {
|
|
|
2976
3123
|
}
|
|
2977
3124
|
}
|
|
2978
3125
|
|
|
2979
|
-
function sendMessage(message, { worker, writer
|
|
3126
|
+
function sendMessage(message, { worker, writer }) {
|
|
2980
3127
|
try {
|
|
2981
|
-
const { value
|
|
2982
|
-
const transferables = [];
|
|
3128
|
+
const { value } = message;
|
|
2983
3129
|
if (value) {
|
|
2984
3130
|
message.value = toExactUint8Array(value);
|
|
2985
|
-
transferables.push(message.value.buffer);
|
|
2986
|
-
}
|
|
2987
|
-
if (transferStreams && transferStreamsSupported && workerAlive) {
|
|
2988
|
-
if (readable) {
|
|
2989
|
-
transferables.push(readable);
|
|
2990
|
-
}
|
|
2991
|
-
if (writable) {
|
|
2992
|
-
transferables.push(writable);
|
|
2993
|
-
}
|
|
2994
|
-
} else {
|
|
2995
|
-
message.readable = message.writable = null;
|
|
2996
|
-
}
|
|
2997
|
-
if (transferables.length) {
|
|
2998
3131
|
try {
|
|
2999
|
-
worker.postMessage(message,
|
|
3000
|
-
return true;
|
|
3132
|
+
worker.postMessage(message, [message.value.buffer]);
|
|
3001
3133
|
} catch {
|
|
3002
|
-
transferStreamsSupported = false;
|
|
3003
|
-
message.readable = message.writable = null;
|
|
3004
3134
|
worker.postMessage(message);
|
|
3005
3135
|
}
|
|
3006
3136
|
} else {
|
|
@@ -3079,9 +3209,6 @@ function getResponseError(errorData, errorValue) {
|
|
|
3079
3209
|
responseError = errorValue.value;
|
|
3080
3210
|
} else {
|
|
3081
3211
|
responseError = Object.assign(new Error(message), { stack, code, name });
|
|
3082
|
-
if (cause) {
|
|
3083
|
-
responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
|
|
3084
|
-
}
|
|
3085
3212
|
}
|
|
3086
3213
|
if (isErrorObject(responseError)) {
|
|
3087
3214
|
try {
|
|
@@ -3091,6 +3218,14 @@ function getResponseError(errorData, errorValue) {
|
|
|
3091
3218
|
if (codecImportFailed) {
|
|
3092
3219
|
responseError.codecImportFailed = true;
|
|
3093
3220
|
}
|
|
3221
|
+
if (cause) {
|
|
3222
|
+
if (!isErrorObject(responseError.cause)) {
|
|
3223
|
+
responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
|
|
3224
|
+
}
|
|
3225
|
+
if (cause.code !== UNDEFINED_VALUE && responseError.cause.code !== cause.code) {
|
|
3226
|
+
responseError.cause.code = cause.code;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3094
3229
|
if (errorValue) {
|
|
3095
3230
|
if (responseError.name !== name) {
|
|
3096
3231
|
responseError.name = name;
|
|
@@ -3144,7 +3279,7 @@ let indexWorker = 0;
|
|
|
3144
3279
|
|
|
3145
3280
|
async function runWorker(stream, workerOptions) {
|
|
3146
3281
|
const { options, config } = workerOptions;
|
|
3147
|
-
const {
|
|
3282
|
+
const { useWebWorkers, useCompressionStream, compressed, checkCrc32, computeCrc32, encrypted, format, codecURI } = options;
|
|
3148
3283
|
const { workerURI, createWorker, maxWorkers } = config;
|
|
3149
3284
|
if (format) {
|
|
3150
3285
|
if (codecURI) {
|
|
@@ -3152,7 +3287,6 @@ async function runWorker(stream, workerOptions) {
|
|
|
3152
3287
|
}
|
|
3153
3288
|
await ensureCodecStreams(format, options.codecURI);
|
|
3154
3289
|
}
|
|
3155
|
-
workerOptions.transferStreams = !format && (transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams));
|
|
3156
3290
|
const streamCopy = !compressed && !checkCrc32 && !computeCrc32 && !encrypted;
|
|
3157
3291
|
const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
|
|
3158
3292
|
workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
@@ -3699,10 +3833,11 @@ class FetchReader extends Reader {
|
|
|
3699
3833
|
|
|
3700
3834
|
createReadable(options) {
|
|
3701
3835
|
const reader = this;
|
|
3702
|
-
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
3836
|
+
const { useRangeHeader, forceRangeRequests, size, eocdCache } = reader;
|
|
3703
3837
|
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
3704
3838
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3705
|
-
|
|
3839
|
+
const cached = eocdCache && offset >= size - eocdCache.length;
|
|
3840
|
+
if (readSize > 0 && offset < size && !cached) {
|
|
3706
3841
|
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
3707
3842
|
}
|
|
3708
3843
|
}
|
|
@@ -4623,12 +4758,9 @@ const ERR_BAD_FORMAT = "File format is not recognized";
|
|
|
4623
4758
|
const ERR_EOCDR_NOT_FOUND = "End of central directory not found";
|
|
4624
4759
|
const ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND = "End of Zip64 central directory locator not found";
|
|
4625
4760
|
const ERR_CENTRAL_DIRECTORY_NOT_FOUND = "Central directory header not found";
|
|
4626
|
-
const ERR_LOCAL_FILE_HEADER_NOT_FOUND = "Local file header not found";
|
|
4627
|
-
const ERR_EXTRAFIELD_ZIP64_NOT_FOUND = "Zip64 extra field not found";
|
|
4628
4761
|
const ERR_ENCRYPTED = "File contains encrypted entry";
|
|
4629
4762
|
const ERR_UNSUPPORTED_ENCRYPTION = "Encryption method not supported";
|
|
4630
4763
|
const ERR_SPLIT_ZIP_FILE = "Split zip file";
|
|
4631
|
-
const ERR_OVERLAPPING_ENTRY = "Overlapping entry found";
|
|
4632
4764
|
const ERR_ENTRY_DATA_OUT_OF_BOUNDS = "Entry data out of bounds";
|
|
4633
4765
|
const ERR_AMBIGUOUS_ARCHIVE = "Ambiguous archive";
|
|
4634
4766
|
const ERR_ENCRYPTED_CENTRAL_DIRECTORY = "Encrypted central directory is not supported";
|
|
@@ -4647,6 +4779,8 @@ const WARNING_APPENDED_DATA = "appended data";
|
|
|
4647
4779
|
const WARNING_PREPENDED_DATA = "prepended data";
|
|
4648
4780
|
const WARNING_PREPENDED_CENTRAL_DIRECTORY = "prepended central directory";
|
|
4649
4781
|
const WARNING_TRAILING_CENTRAL_DIRECTORY_DATA = "trailing central directory data";
|
|
4782
|
+
const WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET = "mismatched central directory offset";
|
|
4783
|
+
const WARNING_MISSING_ZIP64_EXTRA_FIELD = "missing zip64 extra field";
|
|
4650
4784
|
const WARNING_DUPLICATE_FILENAME = "duplicate filename";
|
|
4651
4785
|
const WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY = "mismatched zip64 end of central directory record";
|
|
4652
4786
|
const WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY = "multiple end of central directory records";
|
|
@@ -4660,7 +4794,7 @@ const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
|
|
|
4660
4794
|
const CHARSET_UTF8 = "utf-8";
|
|
4661
4795
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
4662
4796
|
const CHARSET_CP437 = "cp437";
|
|
4663
|
-
const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
|
|
4797
|
+
const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_STRONG_ENCRYPTION | BITFLAG_LANG_ENCODING_FLAG;
|
|
4664
4798
|
const VENDOR_VERSION_AE_1$1 = 1;
|
|
4665
4799
|
const ZIP64_PROPERTIES = [
|
|
4666
4800
|
[PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
|
|
@@ -4690,8 +4824,9 @@ class ZipReader {
|
|
|
4690
4824
|
constructor(reader, options = {}) {
|
|
4691
4825
|
Object.assign(this, {
|
|
4692
4826
|
reader: new GenericReader(reader),
|
|
4693
|
-
options,
|
|
4694
|
-
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4827
|
+
options: options || {},
|
|
4828
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] },
|
|
4829
|
+
entriesMissingZip64ExtraField: new WeakSet()
|
|
4695
4830
|
});
|
|
4696
4831
|
}
|
|
4697
4832
|
|
|
@@ -4762,16 +4897,22 @@ class ZipReader {
|
|
|
4762
4897
|
directoryDataOffset = getDiskOffset$1(reader, getUint32$1(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
|
|
4763
4898
|
let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4764
4899
|
let endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4900
|
+
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4901
|
+
const locatorOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
4902
|
+
let expectedDirectoryDataOffset = locatorOffset - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
4903
|
+
if (!await startsWithSignature(reader, expectedDirectoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE)) {
|
|
4904
|
+
expectedDirectoryDataOffset = await findZip64EndOfDirectoryOffset(reader, locatorOffset);
|
|
4905
|
+
}
|
|
4906
|
+
if (expectedDirectoryDataOffset !== UNDEFINED_VALUE && expectedDirectoryDataOffset >= 0 &&
|
|
4907
|
+
directoryDataOffset != expectedDirectoryDataOffset) {
|
|
4908
|
+
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4909
|
+
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4910
|
+
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4911
|
+
prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
|
|
4912
|
+
}
|
|
4913
|
+
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4914
|
+
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4772
4915
|
}
|
|
4773
|
-
endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
|
|
4774
|
-
endOfDirectoryView = getDataView(endOfDirectoryArray);
|
|
4775
4916
|
}
|
|
4776
4917
|
if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32$1(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
|
|
4777
4918
|
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
@@ -4809,15 +4950,13 @@ class ZipReader {
|
|
|
4809
4950
|
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY);
|
|
4810
4951
|
}
|
|
4811
4952
|
directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
|
|
4953
|
+
} else if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || diskNumber == MAX_16_BITS) {
|
|
4954
|
+
throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
|
|
4812
4955
|
}
|
|
4813
4956
|
}
|
|
4814
4957
|
let declaredDirectoryDataLength = directoryDataLength;
|
|
4815
4958
|
const centralDirectoryEndOffset = endOfDirectoryInfo.offset -
|
|
4816
4959
|
(zip64EndOfDirectory ? zip64EndOfDirectoryLength + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH : 0);
|
|
4817
|
-
if (directoryDataOffset >= reader.size) {
|
|
4818
|
-
prependedDataLength = reader.size - directoryDataOffset - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4819
|
-
directoryDataOffset = reader.size - directoryDataLength - END_OF_CENTRAL_DIR_LENGTH;
|
|
4820
|
-
}
|
|
4821
4960
|
if (expectedLastDiskNumber != lastDiskNumber) {
|
|
4822
4961
|
throw new Error(ERR_SPLIT_ZIP_FILE);
|
|
4823
4962
|
}
|
|
@@ -4825,33 +4964,64 @@ class ZipReader {
|
|
|
4825
4964
|
throw new Error(ERR_BAD_FORMAT);
|
|
4826
4965
|
}
|
|
4827
4966
|
let offset = 0;
|
|
4828
|
-
let directoryArray =
|
|
4967
|
+
let directoryArray = directoryDataOffset < reader.size ?
|
|
4968
|
+
await readUint8Array(reader, directoryDataOffset, directoryDataLength) :
|
|
4969
|
+
EMPTY_UINT8_ARRAY;
|
|
4829
4970
|
let directoryView = getDataView(directoryArray);
|
|
4830
4971
|
if (directoryDataLength) {
|
|
4831
|
-
|
|
4832
|
-
throw new Error(ERR_BAD_FORMAT);
|
|
4833
|
-
}
|
|
4834
|
-
const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4972
|
+
let expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
|
|
4835
4973
|
if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
|
|
4836
|
-
const storedPointsAtDirectory =
|
|
4974
|
+
const storedPointsAtDirectory = directoryArray.length >= 4 && (
|
|
4975
|
+
getUint32$1(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE ||
|
|
4837
4976
|
Boolean(directoryEncryptionInfo && directoryEncryptionInfo.compressedSize) ||
|
|
4838
|
-
detectEncryptedCentralDirectory(directoryView);
|
|
4977
|
+
detectEncryptedCentralDirectory(directoryView));
|
|
4978
|
+
if (!storedPointsAtDirectory && expectedDirectoryDataOffset < 0) {
|
|
4979
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
4980
|
+
}
|
|
4839
4981
|
let reconcile = !storedPointsAtDirectory;
|
|
4840
|
-
if (
|
|
4841
|
-
|
|
4842
|
-
|
|
4982
|
+
if (expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
|
|
4983
|
+
let expectedPointsAtDirectory = await pointsAtDirectory(reader, expectedDirectoryDataOffset);
|
|
4984
|
+
if (!expectedPointsAtDirectory) {
|
|
4985
|
+
const signatureRecordOffset = await findDigitalSignatureRecordOffset(reader, centralDirectoryEndOffset);
|
|
4986
|
+
const signedDirectoryDataOffset = signatureRecordOffset - directoryDataLength;
|
|
4987
|
+
if (signatureRecordOffset !== UNDEFINED_VALUE && signedDirectoryDataOffset >= 0 &&
|
|
4988
|
+
await pointsAtDirectory(reader, signedDirectoryDataOffset)) {
|
|
4989
|
+
expectedDirectoryDataOffset = signedDirectoryDataOffset;
|
|
4990
|
+
expectedPointsAtDirectory = true;
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
if (storedPointsAtDirectory) {
|
|
4994
|
+
reconcile = expectedPointsAtDirectory;
|
|
4995
|
+
}
|
|
4843
4996
|
}
|
|
4844
|
-
if (reconcile) {
|
|
4997
|
+
if (reconcile && expectedDirectoryDataOffset != directoryDataOffset) {
|
|
4845
4998
|
const originalDirectoryDataOffset = directoryDataOffset;
|
|
4846
4999
|
directoryDataOffset = expectedDirectoryDataOffset;
|
|
4847
|
-
if (directoryDataOffset > originalDirectoryDataOffset) {
|
|
4848
|
-
prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
|
|
4849
|
-
prependedCentralDirectory = storedPointsAtDirectory;
|
|
4850
|
-
}
|
|
4851
5000
|
directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
|
|
4852
5001
|
directoryView = getDataView(directoryArray);
|
|
5002
|
+
const offsetDelta = directoryDataOffset - originalDirectoryDataOffset;
|
|
5003
|
+
const localHeaderOffset = getFirstLocalHeaderOffset(directoryArray, directoryView);
|
|
5004
|
+
const localHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5005
|
+
await startsWithSignature(reader, localHeaderOffset, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5006
|
+
const shiftedLocalHeaderFound = localHeaderOffset !== UNDEFINED_VALUE &&
|
|
5007
|
+
await startsWithSignature(reader, localHeaderOffset + offsetDelta, LOCAL_FILE_HEADER_SIGNATURE);
|
|
5008
|
+
if (offsetDelta > 0 && !(localHeaderFound && !shiftedLocalHeaderFound)) {
|
|
5009
|
+
prependedDataLength += offsetDelta;
|
|
5010
|
+
prependedCentralDirectory = storedPointsAtDirectory;
|
|
5011
|
+
} else {
|
|
5012
|
+
reportAmbiguity(checkAmbiguity, warnings, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET);
|
|
5013
|
+
if (offsetDelta < 0 && !localHeaderFound && shiftedLocalHeaderFound) {
|
|
5014
|
+
prependedDataLength += offsetDelta;
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
4853
5017
|
}
|
|
4854
5018
|
}
|
|
5019
|
+
if (directoryArray.length < 4) {
|
|
5020
|
+
throw new Error(ERR_BAD_FORMAT);
|
|
5021
|
+
}
|
|
5022
|
+
} else if (!filesLength && directoryDataOffset < centralDirectoryEndOffset && diskNumber == lastDiskNumber) {
|
|
5023
|
+
prependedDataLength += centralDirectoryEndOffset - directoryDataOffset;
|
|
5024
|
+
directoryDataOffset = centralDirectoryEndOffset;
|
|
4855
5025
|
}
|
|
4856
5026
|
const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
|
|
4857
5027
|
if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
|
|
@@ -4893,8 +5063,10 @@ class ZipReader {
|
|
|
4893
5063
|
addWarning(warnings, WARNING_WRAPPED_ENTRIES_COUNT);
|
|
4894
5064
|
}
|
|
4895
5065
|
}
|
|
5066
|
+
const entryOptions = Object.assign({}, zipReader.options, options, { [OPTION_STRICTNESS]: strictness });
|
|
5067
|
+
delete entryOptions[OPTION_CHECK_AMBIGUITY];
|
|
4896
5068
|
for (let indexFile = 0; indexFile < filesLength; indexFile++) {
|
|
4897
|
-
const fileEntry = new ZipEntry(reader,
|
|
5069
|
+
const fileEntry = new ZipEntry(reader, entryOptions);
|
|
4898
5070
|
if (offset + CENTRAL_FILE_HEADER_LENGTH > directoryArray.length || getUint32$1(directoryView, offset) != CENTRAL_FILE_HEADER_SIGNATURE) {
|
|
4899
5071
|
if (indexFile == 0 && !decryptedDirectory && (zip64EndOfDirectoryVersion2 || detectEncryptedCentralDirectory(directoryView))) {
|
|
4900
5072
|
throw new Error(ERR_ENCRYPTED_CENTRAL_DIRECTORY);
|
|
@@ -4933,17 +5105,6 @@ class ZipReader {
|
|
|
4933
5105
|
if (filename === UNDEFINED_VALUE) {
|
|
4934
5106
|
filename = decodeText(rawFilename, rawFilenameEncoding);
|
|
4935
5107
|
}
|
|
4936
|
-
if (normalizeFilename) {
|
|
4937
|
-
const normalizedFilename = normalizeFilename(filename);
|
|
4938
|
-
if (normalizedFilename !== UNDEFINED_VALUE) {
|
|
4939
|
-
filename = normalizedFilename;
|
|
4940
|
-
}
|
|
4941
|
-
}
|
|
4942
|
-
if (isUnsafeFilename(filename, filenameValidation)) {
|
|
4943
|
-
const error = new Error(ERR_UNSAFE_FILENAME);
|
|
4944
|
-
error.filename = filename;
|
|
4945
|
-
throw error;
|
|
4946
|
-
}
|
|
4947
5108
|
let comment = decode(rawComment, rawCommentEncoding, TEXT_TYPE_COMMENT);
|
|
4948
5109
|
if (comment === UNDEFINED_VALUE) {
|
|
4949
5110
|
comment = decodeText(rawComment, rawCommentEncoding);
|
|
@@ -4971,16 +5132,42 @@ class ZipReader {
|
|
|
4971
5132
|
filename,
|
|
4972
5133
|
comment
|
|
4973
5134
|
});
|
|
4974
|
-
|
|
5135
|
+
let malformedExtraField;
|
|
5136
|
+
try {
|
|
5137
|
+
malformedExtraField = readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
|
|
5138
|
+
} catch (error) {
|
|
5139
|
+
if (checkAmbiguity || error.message != ERR_EXTRAFIELD_ZIP64_NOT_FOUND) {
|
|
5140
|
+
throw error;
|
|
5141
|
+
}
|
|
5142
|
+
fileEntry.zip64ExtraFieldMissing = true;
|
|
5143
|
+
addWarning(warnings, WARNING_MISSING_ZIP64_EXTRA_FIELD, fileEntry.filename);
|
|
5144
|
+
}
|
|
5145
|
+
filename = fileEntry.filename;
|
|
5146
|
+
if (normalizeFilename) {
|
|
5147
|
+
const normalizedFilename = normalizeFilename(filename);
|
|
5148
|
+
if (normalizedFilename !== UNDEFINED_VALUE) {
|
|
5149
|
+
filename = fileEntry.filename = normalizedFilename;
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
if (isUnsafeFilename(filename, filenameValidation)) {
|
|
5153
|
+
const error = new Error(ERR_UNSAFE_FILENAME);
|
|
5154
|
+
error.filename = filename;
|
|
5155
|
+
throw error;
|
|
5156
|
+
}
|
|
5157
|
+
if (malformedExtraField) {
|
|
4975
5158
|
addWarning(warnings, WARNING_MALFORMED_EXTRA_FIELD, filename);
|
|
4976
5159
|
}
|
|
4977
|
-
fileEntry.offset
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
5160
|
+
if (fileEntry.zip64ExtraFieldMissing && fileEntry.offset == MAX_32_BITS) {
|
|
5161
|
+
startOffset = 0;
|
|
5162
|
+
} else {
|
|
5163
|
+
fileEntry.offset += prependedDataLength;
|
|
5164
|
+
const entryPosition = getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset;
|
|
5165
|
+
startOffset = Math.min(entryPosition, startOffset);
|
|
5166
|
+
if (entryPosition < previousEntryPosition) {
|
|
5167
|
+
addWarning(warnings, WARNING_UNSORTED_CENTRAL_DIRECTORY, filename);
|
|
5168
|
+
}
|
|
5169
|
+
previousEntryPosition = entryPosition;
|
|
4982
5170
|
}
|
|
4983
|
-
previousEntryPosition = entryPosition;
|
|
4984
5171
|
if ((fileEntry.version & MAX_8_BITS) > MAX_KNOWN_VERSION) {
|
|
4985
5172
|
addWarning(warnings, WARNING_UNKNOWN_VERSION, filename);
|
|
4986
5173
|
}
|
|
@@ -5000,11 +5187,12 @@ class ZipReader {
|
|
|
5000
5187
|
const sticky = Boolean(fileEntry.unixMode & FILE_ATTR_UNIX_STICKY_MASK);
|
|
5001
5188
|
const unixType = fileEntry.unixMode === UNDEFINED_VALUE ? unixExternalUpper : fileEntry.unixMode;
|
|
5002
5189
|
const symlink = (unixType & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_SYMLINK;
|
|
5003
|
-
const executable = !symlink && ((fileEntry.unixMode !== UNDEFINED_VALUE)
|
|
5004
|
-
? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
|
|
5005
|
-
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
|
|
5006
5190
|
const modeIsDir = fileEntry.unixMode !== UNDEFINED_VALUE && ((fileEntry.unixMode & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
5007
5191
|
const upperIsDir = ((unixExternalUpper & FILE_ATTR_UNIX_TYPE_MASK) == FILE_ATTR_UNIX_TYPE_DIR);
|
|
5192
|
+
const directory = modeIsDir || upperIsDir || (msDosCompatible && msdosAttributes.directory) || fileEntry.filename.endsWith(DIRECTORY_SIGNATURE);
|
|
5193
|
+
const executable = !symlink && !directory && ((fileEntry.unixMode !== UNDEFINED_VALUE)
|
|
5194
|
+
? ((fileEntry.unixMode & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)
|
|
5195
|
+
: (unixCompatible && ((unixExternalUpper & FILE_ATTR_UNIX_EXECUTABLE_MASK) != 0)));
|
|
5008
5196
|
Object.assign(fileEntry, {
|
|
5009
5197
|
setuid,
|
|
5010
5198
|
setgid,
|
|
@@ -5012,16 +5200,19 @@ class ZipReader {
|
|
|
5012
5200
|
symlink,
|
|
5013
5201
|
unixExternalUpper,
|
|
5014
5202
|
executable,
|
|
5015
|
-
directory
|
|
5203
|
+
directory,
|
|
5016
5204
|
zipCrypto: fileEntry.encrypted && !fileEntry.extraFieldAES
|
|
5017
5205
|
});
|
|
5018
5206
|
const entry = new Entry(fileEntry);
|
|
5019
|
-
|
|
5207
|
+
if (fileEntry.zip64ExtraFieldMissing) {
|
|
5208
|
+
zipReader.entriesMissingZip64ExtraField.add(entry);
|
|
5209
|
+
}
|
|
5210
|
+
entry.getData = (writer, options) => fileEntry.getData(writer, entry, zipReader, options);
|
|
5020
5211
|
entry.arrayBuffer = async options => {
|
|
5021
5212
|
const writer = new TransformStream();
|
|
5022
5213
|
const arrayBufferPromise = streamToBlob(writer.readable).then(blob => blob.arrayBuffer());
|
|
5023
5214
|
arrayBufferPromise.catch(() => { });
|
|
5024
|
-
await fileEntry.getData(writer, entry, zipReader
|
|
5215
|
+
await fileEntry.getData(writer, entry, zipReader,
|
|
5025
5216
|
Object.assign({}, options, { preventClose: false }));
|
|
5026
5217
|
return arrayBufferPromise;
|
|
5027
5218
|
};
|
|
@@ -5068,10 +5259,10 @@ class ZipReader {
|
|
|
5068
5259
|
const extractAppendedData = getOptionValue$1(zipReader, options, OPTION_EXTRACT_APPENDED_DATA);
|
|
5069
5260
|
const splitZipSignatureLength = (checkAmbiguity || extractPrependedData) && filesLength &&
|
|
5070
5261
|
startOffset == SPLIT_ZIP_FILE_SIGNATURE_LENGTH && await startsWithSplitZipMarker(reader) ? SPLIT_ZIP_FILE_SIGNATURE_LENGTH : 0;
|
|
5071
|
-
if (checkAmbiguity && (prependedDataLength || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5262
|
+
if (checkAmbiguity && (prependedDataLength > 0 || (filesLength && startOffset > splitZipSignatureLength))) {
|
|
5072
5263
|
throwAmbiguousArchive(WARNING_PREPENDED_DATA);
|
|
5073
5264
|
}
|
|
5074
|
-
if (prependedDataLength || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
|
|
5265
|
+
if (prependedDataLength > 0 || (filesLength && startOffset > SPLIT_ZIP_FILE_SIGNATURE_LENGTH)) {
|
|
5075
5266
|
addWarning(warnings, WARNING_PREPENDED_DATA);
|
|
5076
5267
|
}
|
|
5077
5268
|
if (prependedCentralDirectory) {
|
|
@@ -5229,8 +5420,12 @@ class ZipEntry {
|
|
|
5229
5420
|
});
|
|
5230
5421
|
}
|
|
5231
5422
|
|
|
5232
|
-
async getData(writer, fileEntry,
|
|
5423
|
+
async getData(writer, fileEntry, zipReader, options = {}) {
|
|
5233
5424
|
const zipEntry = this;
|
|
5425
|
+
const { readRanges, directoryOffset } = zipReader;
|
|
5426
|
+
if (zipEntry.zip64ExtraFieldMissing) {
|
|
5427
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5428
|
+
}
|
|
5234
5429
|
const config = getConfiguration();
|
|
5235
5430
|
const {
|
|
5236
5431
|
reader,
|
|
@@ -5261,8 +5456,8 @@ class ZipEntry {
|
|
|
5261
5456
|
const passThroughCompression = Boolean(passThrough);
|
|
5262
5457
|
const passThroughEncryption = passThrough === true;
|
|
5263
5458
|
checkPasswordOption(password, rawPassword);
|
|
5264
|
-
password = password && password.length
|
|
5265
|
-
rawPassword = rawPassword && rawPassword.length
|
|
5459
|
+
password = password && password.length ? password : UNDEFINED_VALUE;
|
|
5460
|
+
rawPassword = rawPassword && rawPassword.length ? rawPassword : UNDEFINED_VALUE;
|
|
5266
5461
|
if (extraFieldAES) {
|
|
5267
5462
|
if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
|
|
5268
5463
|
throw new Error(ERR_UNSUPPORTED_COMPRESSION);
|
|
@@ -5301,10 +5496,10 @@ class ZipEntry {
|
|
|
5301
5496
|
}
|
|
5302
5497
|
validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, checkLocalFilename, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5303
5498
|
const { lastAccessDate, creationDate, uid, gid } = localDirectory;
|
|
5304
|
-
if (lastAccessDate) {
|
|
5499
|
+
if (lastAccessDate && fileEntry.lastAccessDate === UNDEFINED_VALUE) {
|
|
5305
5500
|
fileEntry.lastAccessDate = lastAccessDate;
|
|
5306
5501
|
}
|
|
5307
|
-
if (creationDate) {
|
|
5502
|
+
if (creationDate && fileEntry.creationDate === UNDEFINED_VALUE) {
|
|
5308
5503
|
fileEntry.creationDate = creationDate;
|
|
5309
5504
|
}
|
|
5310
5505
|
if (uid !== UNDEFINED_VALUE && fileEntry.uid === UNDEFINED_VALUE) {
|
|
@@ -5314,12 +5509,12 @@ class ZipEntry {
|
|
|
5314
5509
|
fileEntry.gid = gid;
|
|
5315
5510
|
}
|
|
5316
5511
|
const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
|
|
5317
|
-
const encrypted = zipEntry.encrypted &&
|
|
5512
|
+
const encrypted = zipEntry.encrypted && (!passThroughEncryption || checkPasswordOnly);
|
|
5318
5513
|
const zipCrypto = encrypted && !extraFieldAES;
|
|
5319
5514
|
if (!passThroughEncryption) {
|
|
5320
5515
|
fileEntry.zipCrypto = zipCrypto;
|
|
5321
5516
|
}
|
|
5322
|
-
if (encrypted && (
|
|
5517
|
+
if (encrypted && (zipEntry.rawBitFlag & BITFLAG_STRONG_ENCRYPTION) == BITFLAG_STRONG_ENCRYPTION) {
|
|
5323
5518
|
throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
|
|
5324
5519
|
}
|
|
5325
5520
|
const registeredCodec = passThroughCompression ? UNDEFINED_VALUE : getRegisteredCodec(compressionMethod);
|
|
@@ -5333,7 +5528,7 @@ class ZipEntry {
|
|
|
5333
5528
|
throw new Error(ERR_ENCRYPTED);
|
|
5334
5529
|
}
|
|
5335
5530
|
}
|
|
5336
|
-
if (dataOffset + compressedSize > reader.size) {
|
|
5531
|
+
if (dataOffset + compressedSize > Math.min(reader.size, directoryOffset)) {
|
|
5337
5532
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5338
5533
|
}
|
|
5339
5534
|
const size = compressedSize;
|
|
@@ -5375,7 +5570,6 @@ class ZipEntry {
|
|
|
5375
5570
|
encrypted,
|
|
5376
5571
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
5377
5572
|
useCompressionStream,
|
|
5378
|
-
transferStreams: getOptionValue$1(zipEntry, options, OPTION_TRANSFER_STREAMS),
|
|
5379
5573
|
deflate64,
|
|
5380
5574
|
format: registeredCodec ? registeredCodec.format : UNDEFINED_VALUE,
|
|
5381
5575
|
codecURI: registeredCodec ? registeredCodec.codecURI : UNDEFINED_VALUE,
|
|
@@ -5400,6 +5594,7 @@ class ZipEntry {
|
|
|
5400
5594
|
extraFieldZip64: extraFieldZip64 || localDirectory.extraFieldZip64,
|
|
5401
5595
|
readRanges
|
|
5402
5596
|
});
|
|
5597
|
+
validateDataDescriptor(zipEntry, localDirectory, checkLocalDirectory ? UNDEFINED_VALUE : warnings);
|
|
5403
5598
|
}
|
|
5404
5599
|
let writable, abortError, aborted;
|
|
5405
5600
|
try {
|
|
@@ -5412,16 +5607,14 @@ class ZipEntry {
|
|
|
5412
5607
|
({ writable } = writer);
|
|
5413
5608
|
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5414
5609
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5610
|
+
throwIfAborted(signal);
|
|
5415
5611
|
if (writtenSize != outputSize) {
|
|
5416
5612
|
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
5417
5613
|
}
|
|
5418
5614
|
writer.size += writtenSize;
|
|
5419
5615
|
}
|
|
5420
5616
|
} catch (error) {
|
|
5421
|
-
|
|
5422
|
-
if (failedOutputSize !== UNDEFINED_VALUE) {
|
|
5423
|
-
writer.size += failedOutputSize;
|
|
5424
|
-
} else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5617
|
+
if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
|
|
5425
5618
|
writer.size += error.outputSize;
|
|
5426
5619
|
}
|
|
5427
5620
|
if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
|
|
@@ -5449,13 +5642,7 @@ class ZipEntry {
|
|
|
5449
5642
|
}
|
|
5450
5643
|
|
|
5451
5644
|
function detectEncryptedCentralDirectory(directoryView) {
|
|
5452
|
-
|
|
5453
|
-
for (let offset = 0; offset < maxOffset; offset++) {
|
|
5454
|
-
if (getUint32$1(directoryView, offset) == ARCHIVE_EXTRA_DATA_SIGNATURE) {
|
|
5455
|
-
return true;
|
|
5456
|
-
}
|
|
5457
|
-
}
|
|
5458
|
-
return false;
|
|
5645
|
+
return directoryView.byteLength >= 4 && getUint32$1(directoryView, 0) == ARCHIVE_EXTRA_DATA_SIGNATURE;
|
|
5459
5646
|
}
|
|
5460
5647
|
|
|
5461
5648
|
function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
@@ -5468,6 +5655,70 @@ function getWrappedFilesLength(directoryView, directoryArray, offset) {
|
|
|
5468
5655
|
return wrappedFilesLength % (MAX_16_BITS + 1) ? 0 : wrappedFilesLength;
|
|
5469
5656
|
}
|
|
5470
5657
|
|
|
5658
|
+
function pointsAtDirectory(reader, offset) {
|
|
5659
|
+
return startsWithSignature(reader, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
5660
|
+
}
|
|
5661
|
+
|
|
5662
|
+
async function startsWithSignature(reader, offset, signature) {
|
|
5663
|
+
if (offset < 0 || offset + 4 > reader.size) {
|
|
5664
|
+
return false;
|
|
5665
|
+
}
|
|
5666
|
+
const signatureArray = await readUint8Array(reader, offset, 4);
|
|
5667
|
+
return getUint32$1(getDataView(signatureArray), 0) == signature;
|
|
5668
|
+
}
|
|
5669
|
+
|
|
5670
|
+
async function findDigitalSignatureRecordOffset(reader, endOffset) {
|
|
5671
|
+
const startOffset = Math.max(0, endOffset - (6 + MAX_16_BITS));
|
|
5672
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5673
|
+
const tailView = getDataView(tailArray);
|
|
5674
|
+
for (let indexByte = tailArray.length - 6; indexByte >= 0; indexByte--) {
|
|
5675
|
+
if (getUint32$1(tailView, indexByte) == DIGITAL_SIGNATURE_RECORD_SIGNATURE &&
|
|
5676
|
+
indexByte + 6 + getUint16$1(tailView, indexByte + 4) == tailArray.length) {
|
|
5677
|
+
return startOffset + indexByte;
|
|
5678
|
+
}
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
|
|
5682
|
+
async function findZip64EndOfDirectoryOffset(reader, endOffset) {
|
|
5683
|
+
const startOffset = Math.max(0, endOffset - (ZIP64_END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS));
|
|
5684
|
+
const tailArray = await readUint8Array(reader, startOffset, endOffset - startOffset);
|
|
5685
|
+
const tailView = getDataView(tailArray);
|
|
5686
|
+
for (let indexByte = tailArray.length - ZIP64_END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
|
|
5687
|
+
if (getUint32$1(tailView, indexByte) == ZIP64_END_OF_CENTRAL_DIR_SIGNATURE &&
|
|
5688
|
+
indexByte + 12 + Number(tailView.getBigUint64(indexByte + 4, true)) == tailArray.length) {
|
|
5689
|
+
return startOffset + indexByte;
|
|
5690
|
+
}
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
|
|
5694
|
+
function getFirstLocalHeaderOffset(directoryArray, directoryView) {
|
|
5695
|
+
if (directoryArray.length < CENTRAL_FILE_HEADER_LENGTH) {
|
|
5696
|
+
return UNDEFINED_VALUE;
|
|
5697
|
+
}
|
|
5698
|
+
const localHeaderOffset = getUint32$1(directoryView, 42);
|
|
5699
|
+
if (localHeaderOffset != MAX_32_BITS) {
|
|
5700
|
+
return localHeaderOffset;
|
|
5701
|
+
}
|
|
5702
|
+
let offsetExtraField = CENTRAL_FILE_HEADER_LENGTH + getUint16$1(directoryView, 28);
|
|
5703
|
+
const endExtraField = Math.min(offsetExtraField + getUint16$1(directoryView, 30), directoryArray.length);
|
|
5704
|
+
while (offsetExtraField + 4 <= endExtraField) {
|
|
5705
|
+
const type = getUint16$1(directoryView, offsetExtraField);
|
|
5706
|
+
const size = getUint16$1(directoryView, offsetExtraField + 2);
|
|
5707
|
+
if (type == EXTRAFIELD_TYPE_ZIP64) {
|
|
5708
|
+
let offsetValue = offsetExtraField + 4;
|
|
5709
|
+
if (getUint32$1(directoryView, 24) == MAX_32_BITS) {
|
|
5710
|
+
offsetValue += 8;
|
|
5711
|
+
}
|
|
5712
|
+
if (getUint32$1(directoryView, 20) == MAX_32_BITS) {
|
|
5713
|
+
offsetValue += 8;
|
|
5714
|
+
}
|
|
5715
|
+
return offsetValue + 8 <= endExtraField ? getBigUint64(directoryView, offsetValue) : UNDEFINED_VALUE;
|
|
5716
|
+
}
|
|
5717
|
+
offsetExtraField += 4 + size;
|
|
5718
|
+
}
|
|
5719
|
+
return UNDEFINED_VALUE;
|
|
5720
|
+
}
|
|
5721
|
+
|
|
5471
5722
|
function readDigitalSignature(signatureRecordArray) {
|
|
5472
5723
|
if (signatureRecordArray.length >= 6) {
|
|
5473
5724
|
const signatureRecordView = getDataView(signatureRecordArray);
|
|
@@ -5557,9 +5808,18 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5557
5808
|
uncompressedSize: getUint32$1(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5558
5809
|
});
|
|
5559
5810
|
const extraFieldZip64 = extraField.get(EXTRAFIELD_TYPE_ZIP64);
|
|
5811
|
+
let extraFieldZip64Missing;
|
|
5560
5812
|
if (extraFieldZip64) {
|
|
5561
|
-
readExtraFieldZip64(extraFieldZip64, directory)
|
|
5813
|
+
if (!readExtraFieldZip64(extraFieldZip64, directory, localDirectory)) {
|
|
5814
|
+
malformedExtraField = true;
|
|
5815
|
+
}
|
|
5562
5816
|
directory.extraFieldZip64 = extraFieldZip64;
|
|
5817
|
+
} else if (ZIP64_PROPERTIES.some(([propertyName, max]) => directory[propertyName] == max)) {
|
|
5818
|
+
if (localDirectory) {
|
|
5819
|
+
malformedExtraField = true;
|
|
5820
|
+
} else {
|
|
5821
|
+
extraFieldZip64Missing = true;
|
|
5822
|
+
}
|
|
5563
5823
|
}
|
|
5564
5824
|
const extraFieldUnicodePath = extraField.get(EXTRAFIELD_TYPE_UNICODE_PATH);
|
|
5565
5825
|
if (extraFieldUnicodePath) {
|
|
@@ -5572,10 +5832,13 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5572
5832
|
directory.extraFieldUnicodeComment = extraFieldUnicodeComment;
|
|
5573
5833
|
}
|
|
5574
5834
|
const extraFieldAES = extraField.get(EXTRAFIELD_TYPE_AES);
|
|
5575
|
-
if (extraFieldAES && extraFieldAES.data.length >= 7) {
|
|
5835
|
+
if (extraFieldAES && (compressionMethod == COMPRESSION_METHOD_AES || directory.encrypted) && extraFieldAES.data.length >= 7) {
|
|
5576
5836
|
readExtraFieldAES(extraFieldAES, directory, compressionMethod);
|
|
5577
5837
|
directory.extraFieldAES = extraFieldAES;
|
|
5578
5838
|
} else {
|
|
5839
|
+
if (extraFieldAES) {
|
|
5840
|
+
malformedExtraField = true;
|
|
5841
|
+
}
|
|
5579
5842
|
directory.compressionMethod = compressionMethod;
|
|
5580
5843
|
}
|
|
5581
5844
|
const extraFieldPkwareUnix = extraField.get(EXTRAFIELD_TYPE_PKWARE_UNIX);
|
|
@@ -5588,50 +5851,66 @@ function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory
|
|
|
5588
5851
|
readExtraFieldUnixDates(extraFieldUnixType1, directory);
|
|
5589
5852
|
directory.extraFieldUnixType1 = extraFieldUnixType1;
|
|
5590
5853
|
}
|
|
5854
|
+
const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
5855
|
+
if (extraFieldExtendedTimestamp) {
|
|
5856
|
+
readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
|
|
5857
|
+
directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
|
|
5858
|
+
}
|
|
5591
5859
|
const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS);
|
|
5592
5860
|
if (extraFieldNTFS) {
|
|
5593
5861
|
readExtraFieldNTFS(extraFieldNTFS, directory);
|
|
5594
5862
|
directory.extraFieldNTFS = extraFieldNTFS;
|
|
5595
5863
|
}
|
|
5596
|
-
const
|
|
5864
|
+
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
5597
5865
|
let unixIdsRead;
|
|
5866
|
+
if (extraFieldInfoZip) {
|
|
5867
|
+
unixIdsRead = readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
5868
|
+
directory.extraFieldInfoZip = extraFieldInfoZip;
|
|
5869
|
+
}
|
|
5870
|
+
const extraFieldUnix = extraField.get(EXTRAFIELD_TYPE_UNIX);
|
|
5598
5871
|
if (extraFieldUnix) {
|
|
5599
|
-
|
|
5872
|
+
readExtraFieldUnix(extraFieldUnix, unixIdsRead ? {} : directory, false);
|
|
5600
5873
|
directory.extraFieldUnix = extraFieldUnix;
|
|
5601
5874
|
}
|
|
5602
|
-
if (!unixIdsRead) {
|
|
5603
|
-
const extraFieldInfoZip = extraField.get(EXTRAFIELD_TYPE_INFOZIP);
|
|
5604
|
-
if (extraFieldInfoZip) {
|
|
5605
|
-
readExtraFieldUnix(extraFieldInfoZip, directory, true);
|
|
5606
|
-
directory.extraFieldInfoZip = extraFieldInfoZip;
|
|
5607
|
-
}
|
|
5608
|
-
}
|
|
5609
|
-
const extraFieldExtendedTimestamp = extraField.get(EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
5610
|
-
if (extraFieldExtendedTimestamp) {
|
|
5611
|
-
readExtraFieldExtendedTimestamp(extraFieldExtendedTimestamp, directory, localDirectory);
|
|
5612
|
-
directory.extraFieldExtendedTimestamp = extraFieldExtendedTimestamp;
|
|
5613
|
-
}
|
|
5614
5875
|
const extraFieldUSDZ = extraField.get(EXTRAFIELD_TYPE_USDZ);
|
|
5615
5876
|
if (extraFieldUSDZ) {
|
|
5616
5877
|
directory.extraFieldUSDZ = extraFieldUSDZ;
|
|
5617
5878
|
}
|
|
5879
|
+
if (extraFieldZip64Missing) {
|
|
5880
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5881
|
+
}
|
|
5618
5882
|
return malformedExtraField;
|
|
5619
5883
|
}
|
|
5620
5884
|
|
|
5621
|
-
function readExtraFieldZip64(extraFieldZip64, directory) {
|
|
5885
|
+
function readExtraFieldZip64(extraFieldZip64, directory, localDirectory) {
|
|
5622
5886
|
directory.zip64 = true;
|
|
5623
5887
|
const extraFieldView = getDataView(extraFieldZip64.data);
|
|
5624
5888
|
const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
|
|
5625
5889
|
const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
|
|
5626
5890
|
if (extraFieldZip64.data.length < requiredLength) {
|
|
5891
|
+
if (localDirectory) {
|
|
5892
|
+
return false;
|
|
5893
|
+
}
|
|
5627
5894
|
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
5628
5895
|
}
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5896
|
+
const values = [];
|
|
5897
|
+
try {
|
|
5898
|
+
for (let indexMissingProperty = 0, offset = 0; indexMissingProperty < missingProperties.length; indexMissingProperty++) {
|
|
5899
|
+
const [, max] = missingProperties[indexMissingProperty];
|
|
5900
|
+
const extraction = ZIP64_EXTRACTION[max];
|
|
5901
|
+
values.push(extraction.getValue(extraFieldView, offset));
|
|
5902
|
+
offset += extraction.bytes;
|
|
5903
|
+
}
|
|
5904
|
+
} catch (error) {
|
|
5905
|
+
if (localDirectory) {
|
|
5906
|
+
return false;
|
|
5907
|
+
}
|
|
5908
|
+
throw error;
|
|
5634
5909
|
}
|
|
5910
|
+
missingProperties.forEach(([propertyName], indexMissingProperty) => {
|
|
5911
|
+
directory[propertyName] = extraFieldZip64[propertyName] = values[indexMissingProperty];
|
|
5912
|
+
});
|
|
5913
|
+
return true;
|
|
5635
5914
|
}
|
|
5636
5915
|
|
|
5637
5916
|
function readExtraFieldUnicode(extraFieldUnicode, propertyName, rawPropertyName, directory, fileEntry) {
|
|
@@ -5813,32 +6092,13 @@ async function detectOverlappingEntry({
|
|
|
5813
6092
|
}) {
|
|
5814
6093
|
let dataDescriptorLength = 0;
|
|
5815
6094
|
if (dataDescriptor) {
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
dataDescriptorLength = DATA_DESCRIPTOR_RECORD_LENGTH;
|
|
5820
|
-
}
|
|
5821
|
-
}
|
|
5822
|
-
if (dataDescriptorLength) {
|
|
5823
|
-
const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
|
|
5824
|
-
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
5825
|
-
let signature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
5826
|
-
getUint32$1(dataDescriptorView, 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5827
|
-
if (signature) {
|
|
5828
|
-
const signedDataDescriptor = readDataDescriptor(dataDescriptorView, DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, extraFieldZip64);
|
|
5829
|
-
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || signedDataDescriptor.crc32 == crc32;
|
|
5830
|
-
if (matchCrc32 &&
|
|
5831
|
-
signedDataDescriptor.compressedSize == compressedSize &&
|
|
5832
|
-
signedDataDescriptor.uncompressedSize == uncompressedSize) {
|
|
5833
|
-
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
5834
|
-
} else {
|
|
5835
|
-
signature = false;
|
|
5836
|
-
}
|
|
5837
|
-
}
|
|
5838
|
-
if (dataDescriptorArray.length >= dataDescriptorLength) {
|
|
5839
|
-
const localDataDescriptor = readDataDescriptor(dataDescriptorView, signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0, extraFieldZip64);
|
|
5840
|
-
localDataDescriptor.signature = signature;
|
|
6095
|
+
const zip64 = Boolean(extraFieldZip64);
|
|
6096
|
+
const localDataDescriptor = await readLocalDataDescriptor(reader, dataOffset + compressedSize, { crc32, compressedSize, uncompressedSize, zip64 });
|
|
6097
|
+
if (localDataDescriptor) {
|
|
5841
6098
|
fileEntry.localDirectory.dataDescriptor = localDataDescriptor;
|
|
6099
|
+
dataDescriptorLength = getDataDescriptorLength(localDataDescriptor.zip64, localDataDescriptor.signature);
|
|
6100
|
+
} else {
|
|
6101
|
+
dataDescriptorLength = getDataDescriptorLength(zip64, false);
|
|
5842
6102
|
}
|
|
5843
6103
|
}
|
|
5844
6104
|
const range = {
|
|
@@ -5903,18 +6163,50 @@ function mergeRanges(sortedRanges, pendingRanges) {
|
|
|
5903
6163
|
return mergedRanges;
|
|
5904
6164
|
}
|
|
5905
6165
|
|
|
5906
|
-
function
|
|
6166
|
+
async function readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64 }) {
|
|
6167
|
+
const maxLength = DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
6168
|
+
const length = Math.min(maxLength, Math.max(0, reader.size - offset));
|
|
6169
|
+
const dataDescriptorArray = length ? await readUint8Array(reader, offset, length) : EMPTY_UINT8_ARRAY;
|
|
6170
|
+
const dataDescriptorView = getDataView(dataDescriptorArray);
|
|
6171
|
+
const candidates = [[zip64, true], [zip64, false], [!zip64, true], [!zip64, false]]
|
|
6172
|
+
.map(([zip64Layout, signature]) => readDataDescriptor(dataDescriptorView, zip64Layout, signature))
|
|
6173
|
+
.filter(candidate => candidate && candidate.compressedSize == compressedSize && candidate.uncompressedSize == uncompressedSize);
|
|
6174
|
+
return candidates.find(candidate => candidate.crc32 == crc32) || candidates[0] ||
|
|
6175
|
+
readDataDescriptor(dataDescriptorView, zip64, true) || readDataDescriptor(dataDescriptorView, zip64, false);
|
|
6176
|
+
}
|
|
6177
|
+
|
|
6178
|
+
async function getEntryDataDescriptorLength(reader, offset, { crc32, compressedSize, uncompressedSize, extraFieldZip64 }) {
|
|
6179
|
+
const dataDescriptor = await readLocalDataDescriptor(reader, offset, { crc32, compressedSize, uncompressedSize, zip64: Boolean(extraFieldZip64) });
|
|
6180
|
+
if (dataDescriptor && dataDescriptor.compressedSize == compressedSize && dataDescriptor.uncompressedSize == uncompressedSize) {
|
|
6181
|
+
return getDataDescriptorLength(dataDescriptor.zip64, dataDescriptor.signature);
|
|
6182
|
+
}
|
|
6183
|
+
}
|
|
6184
|
+
|
|
6185
|
+
function readDataDescriptor(dataDescriptorView, zip64, signature) {
|
|
6186
|
+
const offset = signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0;
|
|
6187
|
+
if (dataDescriptorView.byteLength < getDataDescriptorLength(zip64, signature) ||
|
|
6188
|
+
(signature && getUint32$1(dataDescriptorView, 0) != DATA_DESCRIPTOR_RECORD_SIGNATURE)) {
|
|
6189
|
+
return UNDEFINED_VALUE;
|
|
6190
|
+
}
|
|
5907
6191
|
const crc32 = getUint32$1(dataDescriptorView, offset);
|
|
5908
6192
|
let compressedSize;
|
|
5909
6193
|
let uncompressedSize;
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
6194
|
+
try {
|
|
6195
|
+
if (zip64) {
|
|
6196
|
+
compressedSize = getBigUint64(dataDescriptorView, offset + 4);
|
|
6197
|
+
uncompressedSize = getBigUint64(dataDescriptorView, offset + 12);
|
|
6198
|
+
} else {
|
|
6199
|
+
compressedSize = getUint32$1(dataDescriptorView, offset + 4);
|
|
6200
|
+
uncompressedSize = getUint32$1(dataDescriptorView, offset + 8);
|
|
6201
|
+
}
|
|
6202
|
+
} catch {
|
|
6203
|
+
return UNDEFINED_VALUE;
|
|
5916
6204
|
}
|
|
5917
|
-
return { crc32, compressedSize, uncompressedSize };
|
|
6205
|
+
return { signature, zip64, crc32, compressedSize, uncompressedSize };
|
|
6206
|
+
}
|
|
6207
|
+
|
|
6208
|
+
function getDataDescriptorLength(zip64, signature) {
|
|
6209
|
+
return (zip64 ? DATA_DESCRIPTOR_RECORD_ZIP_64_LENGTH : DATA_DESCRIPTOR_RECORD_LENGTH) + (signature ? DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH : 0);
|
|
5918
6210
|
}
|
|
5919
6211
|
|
|
5920
6212
|
function getDiskOffset$1(reader, diskNumber) {
|
|
@@ -6023,7 +6315,7 @@ function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
|
6023
6315
|
async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDataSize) {
|
|
6024
6316
|
const { size } = reader;
|
|
6025
6317
|
const anchoredLength = Math.min(size, END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS);
|
|
6026
|
-
const remoteProbeBudget = {
|
|
6318
|
+
const remoteProbeBudget = { remaining: MAX_END_OF_CENTRAL_DIR_PROBES };
|
|
6027
6319
|
let endOfDirectoryInfo;
|
|
6028
6320
|
let plausibleEndOfDirectoryInfo;
|
|
6029
6321
|
let endOfDirectoryReachingEndCount = 0;
|
|
@@ -6116,8 +6408,8 @@ async function readSignature(reader, view, anchoredOffset, signatureOffset, size
|
|
|
6116
6408
|
if (signatureOffset >= anchoredOffset) {
|
|
6117
6409
|
return getUint32$1(view, signatureOffset - anchoredOffset);
|
|
6118
6410
|
}
|
|
6119
|
-
if (remoteProbeBudget.
|
|
6120
|
-
remoteProbeBudget.
|
|
6411
|
+
if (remoteProbeBudget.remaining > 0) {
|
|
6412
|
+
remoteProbeBudget.remaining--;
|
|
6121
6413
|
const signatureArray = await readUint8Array(reader, signatureOffset, 4);
|
|
6122
6414
|
return getUint32$1(getDataView(signatureArray), 0);
|
|
6123
6415
|
}
|
|
@@ -6149,6 +6441,18 @@ function validateLocalDirectory(zipEntry, localDirectory, rawLocalFilename, chec
|
|
|
6149
6441
|
}
|
|
6150
6442
|
}
|
|
6151
6443
|
|
|
6444
|
+
function validateDataDescriptor(zipEntry, localDirectory, warnings) {
|
|
6445
|
+
const { dataDescriptor } = localDirectory;
|
|
6446
|
+
const maskedLocalDirectory = zipEntry.decryptedDirectory &&
|
|
6447
|
+
(localDirectory.rawBitFlag & BITFLAG_MASKED_LOCAL_HEADERS) == BITFLAG_MASKED_LOCAL_HEADERS;
|
|
6448
|
+
if (dataDescriptor && !maskedLocalDirectory &&
|
|
6449
|
+
((zipEntry.crc32 !== UNDEFINED_VALUE && dataDescriptor.crc32 != zipEntry.crc32) ||
|
|
6450
|
+
dataDescriptor.compressedSize != zipEntry.compressedSize ||
|
|
6451
|
+
dataDescriptor.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
6452
|
+
reportAmbiguity(!warnings, warnings, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES);
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6455
|
+
|
|
6152
6456
|
function reportAmbiguity(reject, warnings, reason) {
|
|
6153
6457
|
if (reject) {
|
|
6154
6458
|
throwAmbiguousArchive(reason);
|
|
@@ -6207,6 +6511,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6207
6511
|
ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
|
|
6208
6512
|
ERR_BAD_FORMAT: ERR_BAD_FORMAT,
|
|
6209
6513
|
ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
|
|
6514
|
+
ERR_CODEC_OUT_OF_MEMORY: ERR_CODEC_OUT_OF_MEMORY,
|
|
6210
6515
|
ERR_ENCRYPTED: ERR_ENCRYPTED,
|
|
6211
6516
|
ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
|
|
6212
6517
|
ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
|
|
@@ -6233,11 +6538,13 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6233
6538
|
WARNING_COMPRESSED_PATCHED_DATA: WARNING_COMPRESSED_PATCHED_DATA,
|
|
6234
6539
|
WARNING_DUPLICATE_FILENAME: WARNING_DUPLICATE_FILENAME,
|
|
6235
6540
|
WARNING_MALFORMED_EXTRA_FIELD: WARNING_MALFORMED_EXTRA_FIELD,
|
|
6541
|
+
WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET: WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET,
|
|
6236
6542
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG: WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG,
|
|
6237
6543
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD: WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD,
|
|
6238
6544
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES: WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES,
|
|
6239
6545
|
WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME: WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME,
|
|
6240
6546
|
WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY: WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY,
|
|
6547
|
+
WARNING_MISSING_ZIP64_EXTRA_FIELD: WARNING_MISSING_ZIP64_EXTRA_FIELD,
|
|
6241
6548
|
WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY: WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY,
|
|
6242
6549
|
WARNING_PREPENDED_CENTRAL_DIRECTORY: WARNING_PREPENDED_CENTRAL_DIRECTORY,
|
|
6243
6550
|
WARNING_PREPENDED_DATA: WARNING_PREPENDED_DATA,
|
|
@@ -6248,6 +6555,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
|
|
|
6248
6555
|
WARNING_WRAPPED_ENTRIES_COUNT: WARNING_WRAPPED_ENTRIES_COUNT,
|
|
6249
6556
|
ZipReader: ZipReader,
|
|
6250
6557
|
ZipReaderStream: ZipReaderStream,
|
|
6558
|
+
getEntryDataDescriptorLength: getEntryDataDescriptorLength,
|
|
6251
6559
|
isZipFile: isZipFile
|
|
6252
6560
|
});
|
|
6253
6561
|
|
|
@@ -6370,129 +6678,8 @@ class ZipWriter {
|
|
|
6370
6678
|
return watchPromiseError(this, prependZipEntries(this, reader));
|
|
6371
6679
|
}
|
|
6372
6680
|
|
|
6373
|
-
appendZip(reader) {
|
|
6374
|
-
return watchPromiseError(this,
|
|
6375
|
-
}
|
|
6376
|
-
|
|
6377
|
-
async appendZipEntries(reader) {
|
|
6378
|
-
const zipWriter = this;
|
|
6379
|
-
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6380
|
-
while (pendingAddFileCalls.size) {
|
|
6381
|
-
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6382
|
-
}
|
|
6383
|
-
let resolveAppendZip;
|
|
6384
|
-
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6385
|
-
pendingAddFileCalls.add(promiseAppendZip);
|
|
6386
|
-
const appendedFilenames = [];
|
|
6387
|
-
let releaseLockWriter;
|
|
6388
|
-
try {
|
|
6389
|
-
reader = new GenericReader(reader);
|
|
6390
|
-
await initStream(reader);
|
|
6391
|
-
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6392
|
-
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6393
|
-
await initStream(reader);
|
|
6394
|
-
}
|
|
6395
|
-
const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
|
|
6396
|
-
const zipReader$1 = new ZipReader(reader);
|
|
6397
|
-
const entries = await zipReader$1.getEntries();
|
|
6398
|
-
await zipReader$1.close();
|
|
6399
|
-
await initStream(zipWriter.writer);
|
|
6400
|
-
const { directoryOffset } = zipReader$1;
|
|
6401
|
-
entries.forEach(({ filename }) => {
|
|
6402
|
-
if (filenames.has(filename)) {
|
|
6403
|
-
throw new Error(ERR_DUPLICATED_NAME);
|
|
6404
|
-
}
|
|
6405
|
-
filenames.add(filename);
|
|
6406
|
-
appendedFilenames.push(filename);
|
|
6407
|
-
});
|
|
6408
|
-
zipWriter.writerLocked = true;
|
|
6409
|
-
const { lockWriter } = zipWriter;
|
|
6410
|
-
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6411
|
-
zipWriter.writerLocked = false;
|
|
6412
|
-
resolve();
|
|
6413
|
-
});
|
|
6414
|
-
await lockWriter;
|
|
6415
|
-
if (zipWriter.addSplitZipSignature) {
|
|
6416
|
-
delete zipWriter.addSplitZipSignature;
|
|
6417
|
-
if (!await startsWithSplitZipSignature(reader)) {
|
|
6418
|
-
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6419
|
-
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6420
|
-
}
|
|
6421
|
-
}
|
|
6422
|
-
const entryPositions = await copyZipData(zipWriter, reader, entries, directoryOffset);
|
|
6423
|
-
entries.forEach(entry => {
|
|
6424
|
-
const {
|
|
6425
|
-
version,
|
|
6426
|
-
rawLastModDate,
|
|
6427
|
-
rawFilename,
|
|
6428
|
-
bitFlag,
|
|
6429
|
-
encrypted,
|
|
6430
|
-
uncompressedSize,
|
|
6431
|
-
compressedSize,
|
|
6432
|
-
extraFieldZip64
|
|
6433
|
-
} = entry;
|
|
6434
|
-
let {
|
|
6435
|
-
compressionMethod,
|
|
6436
|
-
rawExtraField,
|
|
6437
|
-
} = entry;
|
|
6438
|
-
const { level, languageEncodingFlag, dataDescriptor } = bitFlag;
|
|
6439
|
-
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6440
|
-
if (entry.extraFieldAES) {
|
|
6441
|
-
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6442
|
-
}
|
|
6443
|
-
const extraFieldLength = getLength(rawExtraField);
|
|
6444
|
-
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6445
|
-
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6446
|
-
const bitFlagValue = (getBitFlag(level, languageEncodingFlag, dataDescriptor, encrypted, compressionMethod) & ~BITFLAG_LEVEL) | (level << 1);
|
|
6447
|
-
const {
|
|
6448
|
-
headerArray,
|
|
6449
|
-
headerView
|
|
6450
|
-
} = getHeaderArrayData({
|
|
6451
|
-
version,
|
|
6452
|
-
bitFlag: bitFlagValue,
|
|
6453
|
-
compressionMethod,
|
|
6454
|
-
uncompressedSize,
|
|
6455
|
-
compressedSize,
|
|
6456
|
-
rawLastModDate,
|
|
6457
|
-
rawFilename,
|
|
6458
|
-
zip64CompressedSize,
|
|
6459
|
-
zip64UncompressedSize,
|
|
6460
|
-
extraFieldLength
|
|
6461
|
-
});
|
|
6462
|
-
const { crc32 } = entry;
|
|
6463
|
-
if (crc32 !== UNDEFINED_VALUE) {
|
|
6464
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6465
|
-
}
|
|
6466
|
-
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6467
|
-
Object.assign(entry, {
|
|
6468
|
-
zip64Enabled: true,
|
|
6469
|
-
zip64UncompressedSize,
|
|
6470
|
-
zip64CompressedSize,
|
|
6471
|
-
offset,
|
|
6472
|
-
diskNumberStart,
|
|
6473
|
-
zip64DiskNumberStart: false,
|
|
6474
|
-
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6475
|
-
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6476
|
-
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6477
|
-
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6478
|
-
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6479
|
-
rawExtraField,
|
|
6480
|
-
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6481
|
-
headerArray,
|
|
6482
|
-
headerView
|
|
6483
|
-
});
|
|
6484
|
-
fileEntries.set(entry.filename, entry);
|
|
6485
|
-
});
|
|
6486
|
-
} catch (error) {
|
|
6487
|
-
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6488
|
-
throw error;
|
|
6489
|
-
} finally {
|
|
6490
|
-
resolveAppendZip();
|
|
6491
|
-
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6492
|
-
if (releaseLockWriter) {
|
|
6493
|
-
releaseLockWriter();
|
|
6494
|
-
}
|
|
6495
|
-
}
|
|
6681
|
+
appendZip(reader, options = {}) {
|
|
6682
|
+
return watchPromiseError(this, appendZipEntries(this, reader, options));
|
|
6496
6683
|
}
|
|
6497
6684
|
|
|
6498
6685
|
add(name = "", reader, options = {}) {
|
|
@@ -6654,11 +6841,149 @@ function watchPromiseError(zipWriter, promise) {
|
|
|
6654
6841
|
return watchedPromise;
|
|
6655
6842
|
}
|
|
6656
6843
|
|
|
6844
|
+
async function appendZipEntries(zipWriter, reader, options = {}) {
|
|
6845
|
+
const { pendingAddFileCalls, filenames, fileEntries } = zipWriter;
|
|
6846
|
+
const filter = checkFunctionOption(options.filter);
|
|
6847
|
+
const readerOptions = checkReaderOptionsObject(options.readerOptions);
|
|
6848
|
+
while (pendingAddFileCalls.size) {
|
|
6849
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
6850
|
+
}
|
|
6851
|
+
let resolveAppendZip;
|
|
6852
|
+
const promiseAppendZip = new Promise(resolve => resolveAppendZip = resolve);
|
|
6853
|
+
pendingAddFileCalls.add(promiseAppendZip);
|
|
6854
|
+
const appendedFilenames = [];
|
|
6855
|
+
let releaseLockWriter;
|
|
6856
|
+
try {
|
|
6857
|
+
reader = new GenericReader(reader);
|
|
6858
|
+
await initStream(reader);
|
|
6859
|
+
if (reader.size === UNDEFINED_VALUE || !reader.readUint8Array) {
|
|
6860
|
+
reader = new BlobReader(await streamToBlob(reader.readable));
|
|
6861
|
+
await initStream(reader);
|
|
6862
|
+
}
|
|
6863
|
+
const { ZipReader, getEntryDataDescriptorLength } = await Promise.resolve().then(function () { return zipReader; });
|
|
6864
|
+
const zipReader$1 = new ZipReader(reader, readerOptions);
|
|
6865
|
+
const keptEntries = [];
|
|
6866
|
+
let entries;
|
|
6867
|
+
try {
|
|
6868
|
+
entries = await zipReader$1.getEntries();
|
|
6869
|
+
for (const entry of entries) {
|
|
6870
|
+
if (!filter || await filter(entry, getExistingEntry(fileEntries, entry.filename))) {
|
|
6871
|
+
keptEntries.push(entry);
|
|
6872
|
+
}
|
|
6873
|
+
}
|
|
6874
|
+
} finally {
|
|
6875
|
+
await zipReader$1.close();
|
|
6876
|
+
}
|
|
6877
|
+
await initStream(zipWriter.writer);
|
|
6878
|
+
const { directoryOffset, entriesMissingZip64ExtraField } = zipReader$1;
|
|
6879
|
+
keptEntries.forEach(entry => {
|
|
6880
|
+
const { filename } = entry;
|
|
6881
|
+
if (entriesMissingZip64ExtraField.has(entry)) {
|
|
6882
|
+
throw new Error(ERR_EXTRAFIELD_ZIP64_NOT_FOUND);
|
|
6883
|
+
}
|
|
6884
|
+
if (filenames.has(filename)) {
|
|
6885
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
6886
|
+
}
|
|
6887
|
+
filenames.add(filename);
|
|
6888
|
+
appendedFilenames.push(filename);
|
|
6889
|
+
});
|
|
6890
|
+
zipWriter.writerLocked = true;
|
|
6891
|
+
const { lockWriter } = zipWriter;
|
|
6892
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
6893
|
+
zipWriter.writerLocked = false;
|
|
6894
|
+
resolve();
|
|
6895
|
+
});
|
|
6896
|
+
await lockWriter;
|
|
6897
|
+
if (zipWriter.addSplitZipSignature) {
|
|
6898
|
+
delete zipWriter.addSplitZipSignature;
|
|
6899
|
+
if (filter || !await startsWithSplitZipSignature(reader)) {
|
|
6900
|
+
await writeData(zipWriter.writer, getSplitZipSignatureArray());
|
|
6901
|
+
zipWriter.offset += SPLIT_ZIP_FILE_SIGNATURE_LENGTH;
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
const entryPositions = await copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, Boolean(filter), getEntryDataDescriptorLength);
|
|
6905
|
+
keptEntries.forEach(entry => {
|
|
6906
|
+
const {
|
|
6907
|
+
version,
|
|
6908
|
+
rawLastModDate,
|
|
6909
|
+
rawFilename,
|
|
6910
|
+
rawBitFlag,
|
|
6911
|
+
uncompressedSize,
|
|
6912
|
+
compressedSize,
|
|
6913
|
+
extraFieldZip64
|
|
6914
|
+
} = entry;
|
|
6915
|
+
let {
|
|
6916
|
+
compressionMethod,
|
|
6917
|
+
rawExtraField,
|
|
6918
|
+
} = entry;
|
|
6919
|
+
rawExtraField = removeExtraFieldZip64(rawExtraField || EMPTY_UINT8_ARRAY);
|
|
6920
|
+
if (entry.extraFieldAES) {
|
|
6921
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6922
|
+
}
|
|
6923
|
+
const extraFieldLength = getLength(rawExtraField);
|
|
6924
|
+
const zip64UncompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.uncompressedSize !== UNDEFINED_VALUE;
|
|
6925
|
+
const zip64CompressedSize = Boolean(extraFieldZip64) && extraFieldZip64.compressedSize !== UNDEFINED_VALUE;
|
|
6926
|
+
const {
|
|
6927
|
+
headerArray,
|
|
6928
|
+
headerView
|
|
6929
|
+
} = getHeaderArrayData({
|
|
6930
|
+
version,
|
|
6931
|
+
bitFlag: rawBitFlag,
|
|
6932
|
+
compressionMethod,
|
|
6933
|
+
uncompressedSize,
|
|
6934
|
+
compressedSize,
|
|
6935
|
+
rawLastModDate,
|
|
6936
|
+
rawFilename,
|
|
6937
|
+
zip64CompressedSize,
|
|
6938
|
+
zip64UncompressedSize,
|
|
6939
|
+
extraFieldLength
|
|
6940
|
+
});
|
|
6941
|
+
const { crc32 } = entry;
|
|
6942
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
6943
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6944
|
+
}
|
|
6945
|
+
const { offset, diskNumberStart } = entryPositions.get(entry);
|
|
6946
|
+
fileEntries.set(entry.filename, Object.assign({}, entry, {
|
|
6947
|
+
zip64Enabled: true,
|
|
6948
|
+
zip64UncompressedSize,
|
|
6949
|
+
zip64CompressedSize,
|
|
6950
|
+
offset,
|
|
6951
|
+
diskNumberStart,
|
|
6952
|
+
zip64DiskNumberStart: false,
|
|
6953
|
+
rawExtraFieldZip64: EMPTY_UINT8_ARRAY,
|
|
6954
|
+
rawExtraFieldAES: EMPTY_UINT8_ARRAY,
|
|
6955
|
+
rawExtraFieldExtendedTimestamp: EMPTY_UINT8_ARRAY,
|
|
6956
|
+
rawExtraFieldNTFS: EMPTY_UINT8_ARRAY,
|
|
6957
|
+
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6958
|
+
rawCentralExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6959
|
+
rawExtraField,
|
|
6960
|
+
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6961
|
+
headerArray,
|
|
6962
|
+
headerView
|
|
6963
|
+
}));
|
|
6964
|
+
});
|
|
6965
|
+
} catch (error) {
|
|
6966
|
+
appendedFilenames.forEach(filename => filenames.delete(filename));
|
|
6967
|
+
throw error;
|
|
6968
|
+
} finally {
|
|
6969
|
+
resolveAppendZip();
|
|
6970
|
+
pendingAddFileCalls.delete(promiseAppendZip);
|
|
6971
|
+
if (releaseLockWriter) {
|
|
6972
|
+
releaseLockWriter();
|
|
6973
|
+
}
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
|
|
6977
|
+
function getExistingEntry(fileEntries, filename) {
|
|
6978
|
+
const fileEntry = fileEntries.get(filename);
|
|
6979
|
+
return fileEntry ? new Entry(fileEntry) : UNDEFINED_VALUE;
|
|
6980
|
+
}
|
|
6981
|
+
|
|
6657
6982
|
async function prependZipEntries(zipWriter, reader) {
|
|
6658
6983
|
if (zipWriter.filenames.size) {
|
|
6659
6984
|
throw new Error(ERR_ZIP_NOT_EMPTY);
|
|
6660
6985
|
}
|
|
6661
|
-
await
|
|
6986
|
+
await appendZipEntries(zipWriter, reader);
|
|
6662
6987
|
}
|
|
6663
6988
|
|
|
6664
6989
|
async function addFileEntry(zipWriter, name, reader, options) {
|
|
@@ -7033,16 +7358,17 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
7033
7358
|
const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
|
|
7034
7359
|
const passThroughCompression = Boolean(passThrough);
|
|
7035
7360
|
const passThroughEncryption = passThrough === true;
|
|
7036
|
-
|
|
7037
|
-
|
|
7361
|
+
let password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
|
|
7362
|
+
let rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
|
|
7038
7363
|
checkPasswordOption(password, rawPassword);
|
|
7364
|
+
password = password && password.length ? password : UNDEFINED_VALUE;
|
|
7365
|
+
rawPassword = rawPassword && rawPassword.length ? rawPassword : UNDEFINED_VALUE;
|
|
7039
7366
|
const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
|
|
7040
7367
|
const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
|
|
7041
7368
|
const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
|
|
7042
7369
|
const ntfsTimestamp = getOptionValue(zipWriter, options, OPTION_NTFS_TIMESTAMP);
|
|
7043
7370
|
const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
|
|
7044
7371
|
const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
|
|
7045
|
-
const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
|
|
7046
7372
|
const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
|
|
7047
7373
|
const createTempStream = getFunctionOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
|
|
7048
7374
|
const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
|
|
@@ -7108,7 +7434,6 @@ function resolveMetadata(zipWriter, name, options) {
|
|
|
7108
7434
|
ntfsTimestamp,
|
|
7109
7435
|
keepOrder,
|
|
7110
7436
|
useWebWorkers,
|
|
7111
|
-
transferStreams,
|
|
7112
7437
|
bufferedWrite,
|
|
7113
7438
|
createTempStream,
|
|
7114
7439
|
dataDescriptorSignature,
|
|
@@ -7167,7 +7492,7 @@ async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, op
|
|
|
7167
7492
|
if (reader) {
|
|
7168
7493
|
reader = new GenericReader(reader);
|
|
7169
7494
|
await initStream(reader);
|
|
7170
|
-
if (!reader.
|
|
7495
|
+
if (!reader.readUint8Array && !reader.readable) {
|
|
7171
7496
|
throw new Error(ERR_INVALID_READER);
|
|
7172
7497
|
}
|
|
7173
7498
|
({ size: contentSize } = reader);
|
|
@@ -7430,6 +7755,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7430
7755
|
extraFieldExtendedTimestampTime,
|
|
7431
7756
|
rawExtraFieldNTFS,
|
|
7432
7757
|
rawExtraFieldUnix,
|
|
7758
|
+
rawCentralExtraFieldUnix,
|
|
7433
7759
|
rawExtraFieldAES,
|
|
7434
7760
|
} = headerInfo;
|
|
7435
7761
|
const { dataDescriptorArray } = dataDescriptorInfo;
|
|
@@ -7454,7 +7780,6 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7454
7780
|
rawExtraField,
|
|
7455
7781
|
rawCentralExtraField,
|
|
7456
7782
|
useWebWorkers,
|
|
7457
|
-
transferStreams,
|
|
7458
7783
|
onstart,
|
|
7459
7784
|
onprogress,
|
|
7460
7785
|
onend,
|
|
@@ -7496,6 +7821,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7496
7821
|
rawExtraFieldExtendedTimestamp,
|
|
7497
7822
|
rawExtraFieldNTFS,
|
|
7498
7823
|
rawExtraFieldUnix,
|
|
7824
|
+
rawCentralExtraFieldUnix,
|
|
7499
7825
|
rawExtraFieldAES,
|
|
7500
7826
|
rawExtraField,
|
|
7501
7827
|
rawCentralExtraField,
|
|
@@ -7542,7 +7868,6 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7542
7868
|
encrypted: encrypted && !passThroughEncryption,
|
|
7543
7869
|
useWebWorkers,
|
|
7544
7870
|
useCompressionStream,
|
|
7545
|
-
transferStreams,
|
|
7546
7871
|
format,
|
|
7547
7872
|
codecURI,
|
|
7548
7873
|
compressionMethod
|
|
@@ -7554,6 +7879,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7554
7879
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
7555
7880
|
compressedSize = result.outputSize;
|
|
7556
7881
|
writer.size += compressedSize;
|
|
7882
|
+
throwIfAborted(signal);
|
|
7557
7883
|
if (!passThroughCompression) {
|
|
7558
7884
|
uncompressedSize = result.inputSize;
|
|
7559
7885
|
if (!encrypted || zipCrypto) {
|
|
@@ -7719,6 +8045,7 @@ function getHeaderInfo(options) {
|
|
|
7719
8045
|
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = EMPTY_UINT8_ARRAY;
|
|
7720
8046
|
}
|
|
7721
8047
|
let rawExtraFieldUnix;
|
|
8048
|
+
let rawCentralExtraFieldUnix;
|
|
7722
8049
|
try {
|
|
7723
8050
|
const { uid, gid, unixExtraFieldType } = options;
|
|
7724
8051
|
if (unixExtraFieldType == INFOZIP_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
@@ -7733,7 +8060,7 @@ function getHeaderInfo(options) {
|
|
|
7733
8060
|
extraFieldUnix.writeBytes(uidBytes);
|
|
7734
8061
|
extraFieldUnix.writeUint8(gidBytes.length);
|
|
7735
8062
|
extraFieldUnix.writeBytes(gidBytes);
|
|
7736
|
-
rawExtraFieldUnix = extraFieldUnix.array;
|
|
8063
|
+
rawExtraFieldUnix = rawCentralExtraFieldUnix = extraFieldUnix.array;
|
|
7737
8064
|
} else if (unixExtraFieldType == UNIX_EXTRA_FIELD_TYPE && (uid !== UNDEFINED_VALUE || gid !== UNDEFINED_VALUE)) {
|
|
7738
8065
|
const extraFieldUnix = createRecordWriter(8);
|
|
7739
8066
|
extraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
@@ -7741,11 +8068,15 @@ function getHeaderInfo(options) {
|
|
|
7741
8068
|
extraFieldUnix.writeUint16((uid === UNDEFINED_VALUE ? 0 : uid) & MAX_16_BITS);
|
|
7742
8069
|
extraFieldUnix.writeUint16((gid === UNDEFINED_VALUE ? 0 : gid) & MAX_16_BITS);
|
|
7743
8070
|
rawExtraFieldUnix = extraFieldUnix.array;
|
|
8071
|
+
const centralExtraFieldUnix = createRecordWriter(4);
|
|
8072
|
+
centralExtraFieldUnix.writeUint16(EXTRAFIELD_TYPE_UNIX);
|
|
8073
|
+
centralExtraFieldUnix.writeUint16(0);
|
|
8074
|
+
rawCentralExtraFieldUnix = centralExtraFieldUnix.array;
|
|
7744
8075
|
} else {
|
|
7745
|
-
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
8076
|
+
rawExtraFieldUnix = rawCentralExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
7746
8077
|
}
|
|
7747
8078
|
} catch {
|
|
7748
|
-
rawExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
8079
|
+
rawExtraFieldUnix = rawCentralExtraFieldUnix = EMPTY_UINT8_ARRAY;
|
|
7749
8080
|
}
|
|
7750
8081
|
if (compressionMethod === UNDEFINED_VALUE) {
|
|
7751
8082
|
compressionMethod = compressed ? COMPRESSION_METHOD_DEFLATE : COMPRESSION_METHOD_STORE;
|
|
@@ -7837,6 +8168,7 @@ function getHeaderInfo(options) {
|
|
|
7837
8168
|
rawExtraFieldExtendedTimestamp,
|
|
7838
8169
|
rawExtraFieldNTFS,
|
|
7839
8170
|
rawExtraFieldUnix,
|
|
8171
|
+
rawCentralExtraFieldUnix,
|
|
7840
8172
|
rawExtraFieldAES,
|
|
7841
8173
|
extraFieldLength
|
|
7842
8174
|
};
|
|
@@ -8012,7 +8344,7 @@ function createDirectoryRecords(files) {
|
|
|
8012
8344
|
rawExtraFieldAES,
|
|
8013
8345
|
rawComment,
|
|
8014
8346
|
rawExtraFieldNTFS,
|
|
8015
|
-
|
|
8347
|
+
rawCentralExtraFieldUnix,
|
|
8016
8348
|
rawExtraField,
|
|
8017
8349
|
rawCentralExtraField,
|
|
8018
8350
|
extraFieldExtendedTimestampFlag,
|
|
@@ -8074,7 +8406,7 @@ function createDirectoryRecords(files) {
|
|
|
8074
8406
|
rawExtraFieldZip64,
|
|
8075
8407
|
rawExtraFieldAES,
|
|
8076
8408
|
rawExtraFieldNTFS,
|
|
8077
|
-
|
|
8409
|
+
rawCentralExtraFieldUnix,
|
|
8078
8410
|
rawExtraFieldTimestamp,
|
|
8079
8411
|
rawExtraField,
|
|
8080
8412
|
rawCentralExtraField);
|
|
@@ -8103,7 +8435,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
8103
8435
|
rawExtraFieldAES,
|
|
8104
8436
|
rawExtraFieldExtendedTimestamp,
|
|
8105
8437
|
rawExtraFieldNTFS,
|
|
8106
|
-
|
|
8438
|
+
rawCentralExtraFieldUnix,
|
|
8107
8439
|
rawExtraField,
|
|
8108
8440
|
rawCentralExtraField,
|
|
8109
8441
|
rawComment,
|
|
@@ -8120,7 +8452,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
8120
8452
|
uncompressedSize,
|
|
8121
8453
|
compressedSize
|
|
8122
8454
|
} = fileEntry;
|
|
8123
|
-
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS,
|
|
8455
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawCentralExtraFieldUnix, rawExtraField, rawCentralExtraField);
|
|
8124
8456
|
const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
8125
8457
|
if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
|
|
8126
8458
|
await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
|
|
@@ -8156,7 +8488,7 @@ async function writeDirectoryRecords(zipWriter, directoryDataLength, options) {
|
|
|
8156
8488
|
directoryRecord.writeBytes(rawExtraFieldAES);
|
|
8157
8489
|
directoryRecord.writeBytes(rawExtraFieldExtendedTimestamp);
|
|
8158
8490
|
directoryRecord.writeBytes(rawExtraFieldNTFS);
|
|
8159
|
-
directoryRecord.writeBytes(
|
|
8491
|
+
directoryRecord.writeBytes(rawCentralExtraFieldUnix);
|
|
8160
8492
|
directoryRecord.writeBytes(rawExtraField);
|
|
8161
8493
|
directoryRecord.writeBytes(rawCentralExtraField);
|
|
8162
8494
|
directoryRecord.writeBytes(rawComment);
|
|
@@ -8325,26 +8657,63 @@ function removeExtraFieldZip64(rawExtraField) {
|
|
|
8325
8657
|
return rawExtraField;
|
|
8326
8658
|
}
|
|
8327
8659
|
|
|
8328
|
-
async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
8660
|
+
async function copyZipData(zipWriter, reader, entries, keptEntries, directoryOffset, compact, getEntryDataDescriptorLength) {
|
|
8329
8661
|
const { writer } = zipWriter;
|
|
8330
8662
|
const entryPositions = new Map();
|
|
8331
|
-
if (writer.closeDisk) {
|
|
8663
|
+
if (writer.closeDisk || compact) {
|
|
8332
8664
|
const sortedEntries = Array.from(entries).sort((firstEntry, secondEntry) =>
|
|
8333
8665
|
getSourceOffset(reader, firstEntry) - getSourceOffset(reader, secondEntry));
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8666
|
+
const regionEnds = getRegionEnds(reader, sortedEntries, directoryOffset);
|
|
8667
|
+
const keptEntrySet = new Set(keptEntries);
|
|
8668
|
+
const localHeaderLengths = new Map();
|
|
8669
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8670
|
+
const entry = sortedEntries[indexEntry];
|
|
8671
|
+
if (keptEntrySet.has(entry)) {
|
|
8672
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8673
|
+
const localHeaderLength = await getLocalHeaderLength(reader, sourceOffset);
|
|
8674
|
+
if (localHeaderLength === UNDEFINED_VALUE) {
|
|
8675
|
+
throw new Error(ERR_LOCAL_FILE_HEADER_NOT_FOUND);
|
|
8676
|
+
}
|
|
8677
|
+
let entryEnd = sourceOffset + localHeaderLength + entry.compressedSize;
|
|
8678
|
+
if (entry.bitFlag.dataDescriptor) {
|
|
8679
|
+
const dataDescriptorLength = await getEntryDataDescriptorLength(reader, entryEnd, entry);
|
|
8680
|
+
entryEnd = dataDescriptorLength === UNDEFINED_VALUE ? Math.max(entryEnd, regionEnds[indexEntry]) : entryEnd + dataDescriptorLength;
|
|
8681
|
+
}
|
|
8682
|
+
if (entryEnd > regionEnds[indexEntry]) {
|
|
8683
|
+
throw new Error(ERR_OVERLAPPING_ENTRY);
|
|
8684
|
+
}
|
|
8685
|
+
regionEnds[indexEntry] = entryEnd;
|
|
8686
|
+
localHeaderLengths.set(entry, localHeaderLength);
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8689
|
+
let copiedOffset = 0;
|
|
8690
|
+
let lastPosition;
|
|
8691
|
+
for (let indexEntry = 0; indexEntry < sortedEntries.length; indexEntry++) {
|
|
8692
|
+
const entry = sortedEntries[indexEntry];
|
|
8693
|
+
if (keptEntrySet.has(entry)) {
|
|
8694
|
+
const sourceOffset = getSourceOffset(reader, entry);
|
|
8695
|
+
if (sourceOffset < copiedOffset) {
|
|
8696
|
+
entryPositions.set(entry, lastPosition);
|
|
8697
|
+
} else {
|
|
8698
|
+
if (!compact) {
|
|
8699
|
+
await copyData(zipWriter, reader, copiedOffset, sourceOffset - copiedOffset);
|
|
8700
|
+
}
|
|
8701
|
+
if (writer.closeDisk && exceedsAvailableSize(writer, localHeaderLengths.get(entry))) {
|
|
8702
|
+
await writer.closeDisk();
|
|
8703
|
+
}
|
|
8704
|
+
lastPosition = {
|
|
8705
|
+
offset: getSegmentOffset(zipWriter, writer),
|
|
8706
|
+
diskNumberStart: getDiskNumber(writer)
|
|
8707
|
+
};
|
|
8708
|
+
entryPositions.set(entry, lastPosition);
|
|
8709
|
+
await copyData(zipWriter, reader, sourceOffset, regionEnds[indexEntry] - sourceOffset);
|
|
8710
|
+
copiedOffset = regionEnds[indexEntry];
|
|
8711
|
+
}
|
|
8712
|
+
}
|
|
8713
|
+
}
|
|
8714
|
+
if (!compact) {
|
|
8715
|
+
await copyData(zipWriter, reader, copiedOffset, directoryOffset - copiedOffset);
|
|
8346
8716
|
}
|
|
8347
|
-
await copyData(zipWriter, reader, copiedLength, directoryOffset - copiedLength);
|
|
8348
8717
|
} else {
|
|
8349
8718
|
const baseOffset = zipWriter.offset;
|
|
8350
8719
|
await copyData(zipWriter, reader, 0, directoryOffset);
|
|
@@ -8356,6 +8725,20 @@ async function copyZipData(zipWriter, reader, entries, directoryOffset) {
|
|
|
8356
8725
|
return entryPositions;
|
|
8357
8726
|
}
|
|
8358
8727
|
|
|
8728
|
+
function getRegionEnds(reader, sortedEntries, directoryOffset) {
|
|
8729
|
+
const regionEnds = new Array(sortedEntries.length);
|
|
8730
|
+
let regionEnd = directoryOffset;
|
|
8731
|
+
for (let indexEntry = sortedEntries.length - 1; indexEntry >= 0; indexEntry--) {
|
|
8732
|
+
const sourceOffset = getSourceOffset(reader, sortedEntries[indexEntry]);
|
|
8733
|
+
const nextEntry = sortedEntries[indexEntry + 1];
|
|
8734
|
+
if (nextEntry && getSourceOffset(reader, nextEntry) > sourceOffset) {
|
|
8735
|
+
regionEnd = Math.min(getSourceOffset(reader, nextEntry), directoryOffset);
|
|
8736
|
+
}
|
|
8737
|
+
regionEnds[indexEntry] = regionEnd;
|
|
8738
|
+
}
|
|
8739
|
+
return regionEnds;
|
|
8740
|
+
}
|
|
8741
|
+
|
|
8359
8742
|
async function copyData(zipWriter, reader, offset, size) {
|
|
8360
8743
|
if (size > 0) {
|
|
8361
8744
|
const { writer } = zipWriter;
|
|
@@ -8363,11 +8746,13 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8363
8746
|
try {
|
|
8364
8747
|
await flushBufferedData(createReadable(reader, { offset, size }), writer, UNDEFINED_VALUE, chunkLength => copiedLength += chunkLength);
|
|
8365
8748
|
} catch (error) {
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8749
|
+
if (copiedLength) {
|
|
8750
|
+
zipWriter.hasCorruptedEntries = true;
|
|
8751
|
+
try {
|
|
8752
|
+
error.corruptedEntry = true;
|
|
8753
|
+
} catch {
|
|
8754
|
+
// ignored
|
|
8755
|
+
}
|
|
8371
8756
|
}
|
|
8372
8757
|
throw error;
|
|
8373
8758
|
} finally {
|
|
@@ -8378,11 +8763,16 @@ async function copyData(zipWriter, reader, offset, size) {
|
|
|
8378
8763
|
}
|
|
8379
8764
|
|
|
8380
8765
|
async function getLocalHeaderLength(reader, offset) {
|
|
8381
|
-
const headerArray =
|
|
8766
|
+
const headerArray = offset >= 0 && offset + HEADER_SIZE <= reader.size ?
|
|
8767
|
+
await readUint8Array(reader, offset, HEADER_SIZE) :
|
|
8768
|
+
EMPTY_UINT8_ARRAY;
|
|
8382
8769
|
if (getLength(headerArray) < HEADER_SIZE) {
|
|
8383
|
-
return
|
|
8770
|
+
return UNDEFINED_VALUE;
|
|
8384
8771
|
}
|
|
8385
8772
|
const headerView = getDataView(headerArray);
|
|
8773
|
+
if (getUint32(headerView, 0) != LOCAL_FILE_HEADER_SIGNATURE) {
|
|
8774
|
+
return UNDEFINED_VALUE;
|
|
8775
|
+
}
|
|
8386
8776
|
return HEADER_SIZE +
|
|
8387
8777
|
getUint16(headerView, HEADER_OFFSET_FILENAME_LENGTH + LOCAL_HEADER_COMMON_OFFSET) +
|
|
8388
8778
|
getUint16(headerView, HEADER_OFFSET_EXTRAFIELD_LENGTH + LOCAL_HEADER_COMMON_OFFSET);
|
|
@@ -8733,7 +9123,7 @@ function formatSupported(StreamClass, format) {
|
|
|
8733
9123
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8734
9124
|
*/
|
|
8735
9125
|
|
|
8736
|
-
const VERSION = "2.
|
|
9126
|
+
const VERSION = "2.22.0";
|
|
8737
9127
|
|
|
8738
9128
|
/*
|
|
8739
9129
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9931,4 +10321,4 @@ setDefaultConfiguration({
|
|
|
9931
10321
|
workerURI: null
|
|
9932
10322
|
});
|
|
9933
10323
|
|
|
9934
|
-
export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, deflateSync as deflateRaw, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, inflateSync as inflateRaw, initStream, isZipFile, readUint8Array, registerCodec, resetConfiguration, terminateWorkers, unregisterCodec };
|
|
10324
|
+
export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_CODEC_OUT_OF_MEMORY, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_READER_OPTIONS, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MISSING_ZIP64_EXTRA_FIELD, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, deflateSync as deflateRaw, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, inflateSync as inflateRaw, initStream, isZipFile, readUint8Array, registerCodec, resetConfiguration, terminateWorkers, unregisterCodec };
|