@zip.js/zip.js 2.8.43 → 2.8.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -37
- package/deno.json +21 -1
- package/dist/zip-core-external.js +194 -159
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +194 -131
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +246 -167
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +244 -139
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +267 -1761
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +269 -1735
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +268 -1734
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +196 -133
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +196 -133
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +195 -132
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +31 -2
- package/index-native.cjs +269 -1735
- package/index-native.min.js +1 -1
- package/index.cjs +268 -1734
- package/index.d.cts +129 -8
- package/index.d.ts +129 -8
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +6 -2
- package/lib/core/codec-worker.js +2 -2
- package/lib/core/constants.js +4 -0
- package/lib/core/options.js +6 -0
- package/lib/core/streams/aes-crypto-stream.js +18 -21
- package/lib/core/streams/codec-stream.js +6 -2
- package/lib/core/streams/common-crypto.js +2 -0
- package/lib/core/streams/zip-entry-stream.js +16 -17
- package/lib/core/util/mime-type-data.js +3 -0
- package/lib/core/util/mime-type.js +23 -1596
- package/lib/core/web-worker-base.js +2 -2
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/web-worker-wasm.js +4 -8
- package/lib/core/zip-entry.js +11 -1
- package/lib/core/zip-fs.js +62 -5
- package/lib/core/zip-reader.js +80 -43
- package/lib/core/zip-writer.js +68 -45
- package/lib/zip-core-external.js +2 -0
- package/lib/zip-core-reader.js +2 -0
- package/lib/zip-fs-core-external.js +2 -0
- package/lib/zip-fs-external.js +2 -0
- package/lib/zip-mime-types.js +2 -0
- package/package.json +9 -3
- package/worker-message-property-names.js +1 -1
package/dist/zip-core.js
CHANGED
|
@@ -71,6 +71,8 @@
|
|
|
71
71
|
const EXTRAFIELD_TYPE_USDZ = 0x1986;
|
|
72
72
|
const EXTRAFIELD_TYPE_INFOZIP = 0x7875;
|
|
73
73
|
const EXTRAFIELD_TYPE_UNIX = 0x7855;
|
|
74
|
+
const EXTRAFIELD_TYPE_UNIX_TYPE1 = 0x5855;
|
|
75
|
+
const EXTRAFIELD_TYPE_PKWARE_UNIX = 0x000d;
|
|
74
76
|
|
|
75
77
|
const BITFLAG_ENCRYPTED = 0b1;
|
|
76
78
|
const BITFLAG_LEVEL = 0b0110;
|
|
@@ -1369,6 +1371,7 @@
|
|
|
1369
1371
|
|
|
1370
1372
|
const ERR_INVALID_PASSWORD = "Invalid password";
|
|
1371
1373
|
const ERR_INVALID_SIGNATURE = "Invalid signature";
|
|
1374
|
+
const ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_SIGNATURE;
|
|
1372
1375
|
const ERR_ABORT_CHECK_PASSWORD = "zipjs-abort-check-password";
|
|
1373
1376
|
const ERR_UNSUPPORTED_CRYPTO_API = "Crypto API not supported";
|
|
1374
1377
|
|
|
@@ -1419,7 +1422,7 @@
|
|
|
1419
1422
|
const DERIVED_BITS_USAGE = ["deriveBits"];
|
|
1420
1423
|
const SALT_LENGTH = [8, 12, 16];
|
|
1421
1424
|
const KEY_LENGTH = [16, 24, 32];
|
|
1422
|
-
const
|
|
1425
|
+
const AUTHENTICATION_CODE_LENGTH = 10;
|
|
1423
1426
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
1424
1427
|
// deno-lint-ignore valid-typeof
|
|
1425
1428
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
@@ -1435,7 +1438,7 @@
|
|
|
1435
1438
|
|
|
1436
1439
|
class AESDecryptionStream extends TransformStream {
|
|
1437
1440
|
|
|
1438
|
-
constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly }) {
|
|
1441
|
+
constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly, checkAuthenticationCode = true }) {
|
|
1439
1442
|
super({
|
|
1440
1443
|
start() {
|
|
1441
1444
|
initAesCrypto(this, password, rawPassword, encryptionStrength);
|
|
@@ -1459,8 +1462,8 @@
|
|
|
1459
1462
|
} else {
|
|
1460
1463
|
await ready;
|
|
1461
1464
|
}
|
|
1462
|
-
const output = new Uint8Array(chunk.length -
|
|
1463
|
-
controller.enqueue(append(aesCrypto, chunk, output, 0,
|
|
1465
|
+
const output = new Uint8Array(chunk.length - AUTHENTICATION_CODE_LENGTH - ((chunk.length - AUTHENTICATION_CODE_LENGTH) % BLOCK_LENGTH));
|
|
1466
|
+
controller.enqueue(append(aesCrypto, chunk, output, 0, AUTHENTICATION_CODE_LENGTH, true));
|
|
1464
1467
|
},
|
|
1465
1468
|
async flush(controller) {
|
|
1466
1469
|
const {
|
|
@@ -1471,8 +1474,8 @@
|
|
|
1471
1474
|
} = this;
|
|
1472
1475
|
if (hmac && ctr) {
|
|
1473
1476
|
await ready;
|
|
1474
|
-
const chunkToDecrypt = subarray(pending, 0, pending.length -
|
|
1475
|
-
const
|
|
1477
|
+
const chunkToDecrypt = subarray(pending, 0, pending.length - AUTHENTICATION_CODE_LENGTH);
|
|
1478
|
+
const originalAuthenticationCode = subarray(pending, pending.length - AUTHENTICATION_CODE_LENGTH);
|
|
1476
1479
|
let decryptedChunkArray = EMPTY_UINT8_ARRAY;
|
|
1477
1480
|
if (chunkToDecrypt.length) {
|
|
1478
1481
|
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
@@ -1480,13 +1483,13 @@
|
|
|
1480
1483
|
const decryptedChunk = ctr.update(encryptedChunk);
|
|
1481
1484
|
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1482
1485
|
}
|
|
1483
|
-
const
|
|
1484
|
-
let
|
|
1485
|
-
for (let
|
|
1486
|
-
|
|
1486
|
+
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1487
|
+
let invalidAuthenticationCode = pending.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1488
|
+
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1489
|
+
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
1487
1490
|
}
|
|
1488
|
-
if (
|
|
1489
|
-
throw new Error(
|
|
1491
|
+
if (invalidAuthenticationCode && checkAuthenticationCode) {
|
|
1492
|
+
throw new Error(ERR_INVALID_AUTHENTICATION_CODE);
|
|
1490
1493
|
}
|
|
1491
1494
|
controller.enqueue(decryptedChunkArray);
|
|
1492
1495
|
}
|
|
@@ -1498,8 +1501,6 @@
|
|
|
1498
1501
|
class AESEncryptionStream extends TransformStream {
|
|
1499
1502
|
|
|
1500
1503
|
constructor({ password, rawPassword, encryptionStrength }) {
|
|
1501
|
-
// deno-lint-ignore prefer-const
|
|
1502
|
-
let stream;
|
|
1503
1504
|
super({
|
|
1504
1505
|
start() {
|
|
1505
1506
|
initAesCrypto(this, password, rawPassword, encryptionStrength);
|
|
@@ -1538,12 +1539,11 @@
|
|
|
1538
1539
|
hmac.update(encryptedChunk);
|
|
1539
1540
|
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1540
1541
|
}
|
|
1541
|
-
|
|
1542
|
-
controller.enqueue(concat(encryptedChunkArray,
|
|
1542
|
+
const authenticationCode = fromBits(codecBytes, hmac.digest()).slice(0, AUTHENTICATION_CODE_LENGTH);
|
|
1543
|
+
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1543
1544
|
}
|
|
1544
1545
|
}
|
|
1545
1546
|
});
|
|
1546
|
-
stream = this;
|
|
1547
1547
|
}
|
|
1548
1548
|
}
|
|
1549
1549
|
|
|
@@ -1556,7 +1556,7 @@
|
|
|
1556
1556
|
});
|
|
1557
1557
|
}
|
|
1558
1558
|
|
|
1559
|
-
function append(aesCrypto, input, output, paddingStart, paddingEnd,
|
|
1559
|
+
function append(aesCrypto, input, output, paddingStart, paddingEnd, verifyAuthenticationCode) {
|
|
1560
1560
|
const {
|
|
1561
1561
|
ctr,
|
|
1562
1562
|
hmac,
|
|
@@ -1570,11 +1570,11 @@
|
|
|
1570
1570
|
let offset;
|
|
1571
1571
|
for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
|
|
1572
1572
|
const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
|
|
1573
|
-
if (
|
|
1573
|
+
if (verifyAuthenticationCode) {
|
|
1574
1574
|
hmac.update(inputChunk);
|
|
1575
1575
|
}
|
|
1576
1576
|
const outputChunk = ctr.update(inputChunk);
|
|
1577
|
-
if (!
|
|
1577
|
+
if (!verifyAuthenticationCode) {
|
|
1578
1578
|
hmac.update(outputChunk);
|
|
1579
1579
|
}
|
|
1580
1580
|
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
@@ -1924,6 +1924,7 @@
|
|
|
1924
1924
|
|
|
1925
1925
|
const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
|
|
1926
1926
|
const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
|
|
1927
|
+
const ERR_INVALID_CRC32 = ERR_INVALID_SIGNATURE;
|
|
1927
1928
|
const ERR_UNSUPPORTED_COMPRESSION$2 = "Compression method not supported";
|
|
1928
1929
|
const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
1929
1930
|
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
@@ -1937,14 +1938,14 @@
|
|
|
1937
1938
|
|
|
1938
1939
|
constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
|
|
1939
1940
|
super({});
|
|
1940
|
-
const { compressed, encrypted, useCompressionStream, zipCrypto,
|
|
1941
|
+
const { compressed, encrypted, useCompressionStream, zipCrypto, computeCrc32, level, deflate64, format, compressionMethod } = options;
|
|
1941
1942
|
const stream = this;
|
|
1942
1943
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
1943
1944
|
let readable = super.readable;
|
|
1944
1945
|
const codecStreams = format && getCodecStreams(format);
|
|
1945
|
-
const useGzipCrc32 =
|
|
1946
|
+
const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) &&
|
|
1946
1947
|
Boolean(useCompressionStream && CompressionStream);
|
|
1947
|
-
if ((!encrypted || zipCrypto) &&
|
|
1948
|
+
if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
|
|
1948
1949
|
crc32Stream = new Crc32Stream();
|
|
1949
1950
|
readable = pipeThrough(readable, crc32Stream);
|
|
1950
1951
|
}
|
|
@@ -1979,14 +1980,9 @@
|
|
|
1979
1980
|
}
|
|
1980
1981
|
}
|
|
1981
1982
|
setReadable(stream, readable, () => {
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
signature = encryptionStream.signature;
|
|
1983
|
+
if ((!encrypted || zipCrypto) && computeCrc32) {
|
|
1984
|
+
stream.crc32 = useGzipCrc32 ? gzipCrc32Stream.crc32 : new DataView(crc32Stream.value.buffer).getUint32(0);
|
|
1985
1985
|
}
|
|
1986
|
-
if ((!encrypted || zipCrypto) && signed) {
|
|
1987
|
-
signature = useGzipCrc32 ? gzipCrc32Stream.signature : new DataView(crc32Stream.value.buffer).getUint32(0);
|
|
1988
|
-
}
|
|
1989
|
-
stream.signature = signature;
|
|
1990
1986
|
});
|
|
1991
1987
|
}
|
|
1992
1988
|
}
|
|
@@ -2024,7 +2020,7 @@
|
|
|
2024
2020
|
},
|
|
2025
2021
|
flush() {
|
|
2026
2022
|
const dataView = getDataView(trailerCandidate);
|
|
2027
|
-
stream.
|
|
2023
|
+
stream.crc32 = dataView.getUint32(0, true);
|
|
2028
2024
|
stream.uncompressedSize = dataView.getUint32(4, true);
|
|
2029
2025
|
}
|
|
2030
2026
|
});
|
|
@@ -2106,7 +2102,7 @@
|
|
|
2106
2102
|
|
|
2107
2103
|
constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
|
|
2108
2104
|
super({});
|
|
2109
|
-
const { zipCrypto, encrypted,
|
|
2105
|
+
const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
|
|
2110
2106
|
let crc32Stream, decryptionStream;
|
|
2111
2107
|
let readable = super.readable;
|
|
2112
2108
|
if (encrypted) {
|
|
@@ -2139,15 +2135,15 @@
|
|
|
2139
2135
|
}
|
|
2140
2136
|
readable = mapInflateStreamError(readable);
|
|
2141
2137
|
}
|
|
2142
|
-
if (
|
|
2138
|
+
if (checkCrc32) {
|
|
2143
2139
|
crc32Stream = new Crc32Stream();
|
|
2144
2140
|
readable = pipeThrough(readable, crc32Stream);
|
|
2145
2141
|
}
|
|
2146
2142
|
setReadable(this, readable, () => {
|
|
2147
|
-
if (
|
|
2148
|
-
const
|
|
2149
|
-
if (
|
|
2150
|
-
throw new Error(
|
|
2143
|
+
if (checkCrc32) {
|
|
2144
|
+
const computedCrc32View = new DataView(crc32Stream.value.buffer);
|
|
2145
|
+
if (crc32 != computedCrc32View.getUint32(0, false)) {
|
|
2146
|
+
throw new Error(ERR_INVALID_CRC32);
|
|
2151
2147
|
}
|
|
2152
2148
|
}
|
|
2153
2149
|
});
|
|
@@ -2371,9 +2367,9 @@
|
|
|
2371
2367
|
}
|
|
2372
2368
|
},
|
|
2373
2369
|
flush() {
|
|
2374
|
-
const {
|
|
2370
|
+
const { crc32 } = stream;
|
|
2375
2371
|
Object.assign(codec, {
|
|
2376
|
-
|
|
2372
|
+
crc32,
|
|
2377
2373
|
inputSize
|
|
2378
2374
|
});
|
|
2379
2375
|
}
|
|
@@ -2672,12 +2668,12 @@
|
|
|
2672
2668
|
.pipeThrough(new ChunkStream(getChunkSize(config)))
|
|
2673
2669
|
.pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
2674
2670
|
const {
|
|
2675
|
-
|
|
2671
|
+
crc32,
|
|
2676
2672
|
inputSize,
|
|
2677
2673
|
outputSize
|
|
2678
2674
|
} = codecStream;
|
|
2679
2675
|
return {
|
|
2680
|
-
|
|
2676
|
+
crc32,
|
|
2681
2677
|
inputSize,
|
|
2682
2678
|
outputSize
|
|
2683
2679
|
};
|
|
@@ -3038,7 +3034,7 @@
|
|
|
3038
3034
|
|
|
3039
3035
|
async function runWorker(stream, workerOptions) {
|
|
3040
3036
|
const { options, config } = workerOptions;
|
|
3041
|
-
const { transferStreams, useWebWorkers, useCompressionStream, compressed,
|
|
3037
|
+
const { transferStreams, useWebWorkers, useCompressionStream, compressed, checkCrc32, computeCrc32, encrypted, format, codecURI } = options;
|
|
3042
3038
|
const { workerURI, maxWorkers } = config;
|
|
3043
3039
|
if (format) {
|
|
3044
3040
|
if (codecURI) {
|
|
@@ -3047,7 +3043,7 @@
|
|
|
3047
3043
|
await ensureCodecStreams(format, options.codecURI);
|
|
3048
3044
|
}
|
|
3049
3045
|
workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
|
|
3050
|
-
const streamCopy = !compressed && !
|
|
3046
|
+
const streamCopy = !compressed && !checkCrc32 && !computeCrc32 && !encrypted;
|
|
3051
3047
|
const workerSupported = format === UNDEFINED_VALUE || Boolean(options.codecURI);
|
|
3052
3048
|
workerOptions.useWebWorkers = !streamCopy && workerSupported && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
3053
3049
|
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
@@ -4271,9 +4267,12 @@
|
|
|
4271
4267
|
const PROPERTY_NAME_EXECUTABLE = "executable";
|
|
4272
4268
|
const PROPERTY_NAME_COMPRESSION_METHOD = "compressionMethod";
|
|
4273
4269
|
const PROPERTY_NAME_SIGNATURE = "signature";
|
|
4270
|
+
const PROPERTY_NAME_CRC32 = "crc32";
|
|
4274
4271
|
const PROPERTY_NAME_EXTRA_FIELD = "extraField";
|
|
4275
4272
|
const PROPERTY_NAME_EXTRA_FIELD_INFOZIP = "extraFieldInfoZip";
|
|
4276
4273
|
const PROPERTY_NAME_EXTRA_FIELD_UNIX = "extraFieldUnix";
|
|
4274
|
+
const PROPERTY_NAME_EXTRA_FIELD_UNIX_TYPE1 = "extraFieldUnixType1";
|
|
4275
|
+
const PROPERTY_NAME_EXTRA_FIELD_PKWARE_UNIX = "extraFieldPkwareUnix";
|
|
4277
4276
|
const PROPERTY_NAME_UID = "uid";
|
|
4278
4277
|
const PROPERTY_NAME_GID = "gid";
|
|
4279
4278
|
const PROPERTY_NAME_UNIX_MODE = "unixMode";
|
|
@@ -4290,6 +4289,7 @@
|
|
|
4290
4289
|
const PROPERTY_NAME_EXTRA_FIELD_AES = "extraFieldAES";
|
|
4291
4290
|
const PROPERTY_NAME_EXTRA_FIELD_NTFS = "extraFieldNTFS";
|
|
4292
4291
|
const PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP = "extraFieldExtendedTimestamp";
|
|
4292
|
+
const PROPERTY_NAME_EXTRA_FIELD_USDZ = "extraFieldUSDZ";
|
|
4293
4293
|
|
|
4294
4294
|
const PROPERTY_NAMES = [
|
|
4295
4295
|
PROPERTY_NAME_FILENAME,
|
|
@@ -4301,6 +4301,7 @@
|
|
|
4301
4301
|
PROPERTY_NAME_COMMENT,
|
|
4302
4302
|
PROPERTY_NAME_RAW_COMMENT,
|
|
4303
4303
|
PROPERTY_NAME_LAST_ACCESS_DATE,
|
|
4304
|
+
PROPERTY_NAME_RAW_LAST_ACCESS_DATE,
|
|
4304
4305
|
PROPERTY_NAME_CREATION_DATE,
|
|
4305
4306
|
PROPERTY_NAME_RAW_CREATION_DATE,
|
|
4306
4307
|
PROPERTY_NAME_OFFSET,
|
|
@@ -4319,9 +4320,12 @@
|
|
|
4319
4320
|
PROPERTY_NAME_EXECUTABLE,
|
|
4320
4321
|
PROPERTY_NAME_COMPRESSION_METHOD,
|
|
4321
4322
|
PROPERTY_NAME_SIGNATURE,
|
|
4323
|
+
PROPERTY_NAME_CRC32,
|
|
4322
4324
|
PROPERTY_NAME_EXTRA_FIELD,
|
|
4323
4325
|
PROPERTY_NAME_EXTRA_FIELD_UNIX,
|
|
4324
4326
|
PROPERTY_NAME_EXTRA_FIELD_INFOZIP,
|
|
4327
|
+
PROPERTY_NAME_EXTRA_FIELD_UNIX_TYPE1,
|
|
4328
|
+
PROPERTY_NAME_EXTRA_FIELD_PKWARE_UNIX,
|
|
4325
4329
|
PROPERTY_NAME_UID,
|
|
4326
4330
|
PROPERTY_NAME_GID,
|
|
4327
4331
|
PROPERTY_NAME_UNIX_MODE,
|
|
@@ -4337,7 +4341,8 @@
|
|
|
4337
4341
|
PROPERTY_NAME_EXTRA_FIELD_UNICODE_COMMENT,
|
|
4338
4342
|
PROPERTY_NAME_EXTRA_FIELD_AES,
|
|
4339
4343
|
PROPERTY_NAME_EXTRA_FIELD_NTFS,
|
|
4340
|
-
PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP
|
|
4344
|
+
PROPERTY_NAME_EXTRA_FIELD_EXTENDED_TIMESTAMP,
|
|
4345
|
+
PROPERTY_NAME_EXTRA_FIELD_USDZ
|
|
4341
4346
|
];
|
|
4342
4347
|
|
|
4343
4348
|
class Entry {
|
|
@@ -4390,6 +4395,8 @@
|
|
|
4390
4395
|
const OPTION_CHECK_OVERLAPPING_ENTRY = "checkOverlappingEntry";
|
|
4391
4396
|
const OPTION_CHECK_AMBIGUITY = "checkAmbiguity";
|
|
4392
4397
|
const OPTION_CHECK_SIGNATURE = "checkSignature";
|
|
4398
|
+
const OPTION_CHECK_CRC32 = "checkCrc32";
|
|
4399
|
+
const OPTION_CHECK_AUTHENTICATION_CODE = "checkAuthenticationCode";
|
|
4393
4400
|
const OPTION_USE_WEB_WORKERS = "useWebWorkers";
|
|
4394
4401
|
const OPTION_USE_COMPRESSION_STREAM = "useCompressionStream";
|
|
4395
4402
|
const OPTION_TRANSFER_STREAMS = "transferStreams";
|
|
@@ -4409,6 +4416,7 @@
|
|
|
4409
4416
|
const OPTION_OFFSET = "offset";
|
|
4410
4417
|
const OPTION_USDZ = "usdz";
|
|
4411
4418
|
const OPTION_UNIX_EXTRA_FIELD_TYPE = "unixExtraFieldType";
|
|
4419
|
+
const OPTION_LOCAL_EXTRA_FIELD = "localExtraField";
|
|
4412
4420
|
const OPTION_STRICTNESS = "strictness";
|
|
4413
4421
|
const OPTION_MAX_APPENDED_DATA_SIZE = "maxAppendedDataSize";
|
|
4414
4422
|
const STRICTNESS_STRICT = "strict";
|
|
@@ -4461,6 +4469,7 @@
|
|
|
4461
4469
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
4462
4470
|
const CHARSET_CP437 = "cp437";
|
|
4463
4471
|
const BITFLAG_AMBIGUITY_MASK = BITFLAG_ENCRYPTED | BITFLAG_DATA_DESCRIPTOR | BITFLAG_LANG_ENCODING_FLAG;
|
|
4472
|
+
const VENDOR_VERSION_AE_1$1 = 1;
|
|
4464
4473
|
const ZIP64_PROPERTIES = [
|
|
4465
4474
|
[PROPERTY_NAME_UNCOMPRESSED_SIZE, MAX_32_BITS],
|
|
4466
4475
|
[PROPERTY_NAME_COMPRESSED_SIZE, MAX_32_BITS],
|
|
@@ -4853,7 +4862,7 @@
|
|
|
4853
4862
|
config,
|
|
4854
4863
|
bitFlag,
|
|
4855
4864
|
rawBitFlag,
|
|
4856
|
-
|
|
4865
|
+
crc32,
|
|
4857
4866
|
rawLastModDate,
|
|
4858
4867
|
uncompressedSize,
|
|
4859
4868
|
compressedSize
|
|
@@ -4940,6 +4949,11 @@
|
|
|
4940
4949
|
if (deflate64) {
|
|
4941
4950
|
useCompressionStream = false;
|
|
4942
4951
|
}
|
|
4952
|
+
const checkCrc32Option = getOptionValue$1(zipEntry, options, OPTION_CHECK_CRC32);
|
|
4953
|
+
const checkCrc32 = (checkCrc32Option === UNDEFINED_VALUE ?
|
|
4954
|
+
getOptionValue$1(zipEntry, options, OPTION_CHECK_SIGNATURE) :
|
|
4955
|
+
checkCrc32Option) && !passThrough &&
|
|
4956
|
+
(!encrypted || zipCrypto || (extraFieldAES && extraFieldAES.vendorVersion == VENDOR_VERSION_AE_1$1));
|
|
4943
4957
|
const workerOptions = {
|
|
4944
4958
|
options: {
|
|
4945
4959
|
codecType: CODEC_INFLATE,
|
|
@@ -4947,10 +4961,11 @@
|
|
|
4947
4961
|
rawPassword,
|
|
4948
4962
|
zipCrypto,
|
|
4949
4963
|
encryptionStrength: extraFieldAES && extraFieldAES.strength,
|
|
4950
|
-
|
|
4951
|
-
|
|
4964
|
+
checkCrc32,
|
|
4965
|
+
checkAuthenticationCode: getOptionValue$1(zipEntry, options, OPTION_CHECK_AUTHENTICATION_CODE),
|
|
4966
|
+
passwordVerification: zipCrypto && (dataDescriptor ? ((rawLastModDate >>> 8) & MAX_8_BITS) : ((crc32 >>> 24) & MAX_8_BITS)),
|
|
4952
4967
|
outputSize: passThrough ? compressedSize : uncompressedSize,
|
|
4953
|
-
|
|
4968
|
+
crc32,
|
|
4954
4969
|
compressed: compressionMethod != 0 && !passThrough,
|
|
4955
4970
|
encrypted,
|
|
4956
4971
|
useWebWorkers: getOptionValue$1(zipEntry, options, OPTION_USE_WEB_WORKERS),
|
|
@@ -4972,7 +4987,7 @@
|
|
|
4972
4987
|
fileEntry,
|
|
4973
4988
|
index,
|
|
4974
4989
|
offset: localHeaderOffset,
|
|
4975
|
-
|
|
4990
|
+
crc32,
|
|
4976
4991
|
compressedSize,
|
|
4977
4992
|
uncompressedSize,
|
|
4978
4993
|
dataOffset,
|
|
@@ -5063,6 +5078,7 @@
|
|
|
5063
5078
|
const compressionMethod = getUint16(dataView, offset + 4);
|
|
5064
5079
|
Object.assign(directory, {
|
|
5065
5080
|
signature: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5081
|
+
crc32: getUint32(dataView, offset + HEADER_OFFSET_SIGNATURE),
|
|
5066
5082
|
compressedSize: getUint32(dataView, offset + HEADER_OFFSET_COMPRESSED_SIZE),
|
|
5067
5083
|
uncompressedSize: getUint32(dataView, offset + HEADER_OFFSET_UNCOMPRESSED_SIZE)
|
|
5068
5084
|
});
|
|
@@ -5088,6 +5104,16 @@
|
|
|
5088
5104
|
} else {
|
|
5089
5105
|
directory.compressionMethod = compressionMethod;
|
|
5090
5106
|
}
|
|
5107
|
+
const extraFieldPkwareUnix = extraField.get(EXTRAFIELD_TYPE_PKWARE_UNIX);
|
|
5108
|
+
if (extraFieldPkwareUnix) {
|
|
5109
|
+
readExtraFieldUnixDates(extraFieldPkwareUnix, directory);
|
|
5110
|
+
directory.extraFieldPkwareUnix = extraFieldPkwareUnix;
|
|
5111
|
+
}
|
|
5112
|
+
const extraFieldUnixType1 = extraField.get(EXTRAFIELD_TYPE_UNIX_TYPE1);
|
|
5113
|
+
if (extraFieldUnixType1) {
|
|
5114
|
+
readExtraFieldUnixDates(extraFieldUnixType1, directory);
|
|
5115
|
+
directory.extraFieldUnixType1 = extraFieldUnixType1;
|
|
5116
|
+
}
|
|
5091
5117
|
const extraFieldNTFS = extraField.get(EXTRAFIELD_TYPE_NTFS);
|
|
5092
5118
|
if (extraFieldNTFS) {
|
|
5093
5119
|
readExtraFieldNTFS(extraFieldNTFS, directory);
|
|
@@ -5137,15 +5163,15 @@
|
|
|
5137
5163
|
return;
|
|
5138
5164
|
}
|
|
5139
5165
|
const extraFieldView = getDataView(extraFieldUnicode.data);
|
|
5140
|
-
const
|
|
5141
|
-
|
|
5142
|
-
const
|
|
5143
|
-
|
|
5144
|
-
const
|
|
5166
|
+
const computedCrc32 = new Crc32();
|
|
5167
|
+
computedCrc32.append(fileEntry[rawPropertyName]);
|
|
5168
|
+
const computedCrc32View = getDataView(new Uint8Array(4));
|
|
5169
|
+
computedCrc32View.setUint32(0, computedCrc32.get(), true);
|
|
5170
|
+
const nameCrc32 = getUint32(extraFieldView, 1);
|
|
5145
5171
|
Object.assign(extraFieldUnicode, {
|
|
5146
5172
|
version: getUint8(extraFieldView, 0),
|
|
5147
5173
|
[propertyName]: decodeText(extraFieldUnicode.data.subarray(5)),
|
|
5148
|
-
valid: !fileEntry.bitFlag.languageEncodingFlag &&
|
|
5174
|
+
valid: !fileEntry.bitFlag.languageEncodingFlag && nameCrc32 == getUint32(computedCrc32View, 0)
|
|
5149
5175
|
});
|
|
5150
5176
|
if (extraFieldUnicode.valid) {
|
|
5151
5177
|
directory[propertyName] = extraFieldUnicode[propertyName];
|
|
@@ -5164,6 +5190,9 @@
|
|
|
5164
5190
|
compressionMethod: getUint16(extraFieldView, 5)
|
|
5165
5191
|
});
|
|
5166
5192
|
directory.compressionMethod = extraFieldAES.compressionMethod;
|
|
5193
|
+
if (extraFieldAES.vendorVersion != VENDOR_VERSION_AE_1$1) {
|
|
5194
|
+
directory.crc32 = UNDEFINED_VALUE;
|
|
5195
|
+
}
|
|
5167
5196
|
}
|
|
5168
5197
|
|
|
5169
5198
|
function readExtraFieldNTFS(extraFieldNTFS, directory) {
|
|
@@ -5182,29 +5211,41 @@
|
|
|
5182
5211
|
} catch {
|
|
5183
5212
|
// ignored
|
|
5184
5213
|
}
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
Object.assign(directory, extraFieldData);
|
|
5202
|
-
}
|
|
5203
|
-
} catch {
|
|
5204
|
-
// ignored
|
|
5214
|
+
if (tag1Data && tag1Data.length == 24) {
|
|
5215
|
+
const tag1View = getDataView(tag1Data);
|
|
5216
|
+
const rawLastModDate = tag1View.getBigUint64(0, true);
|
|
5217
|
+
const rawLastAccessDate = tag1View.getBigUint64(8, true);
|
|
5218
|
+
const rawCreationDate = tag1View.getBigUint64(16, true);
|
|
5219
|
+
Object.assign(extraFieldNTFS, {
|
|
5220
|
+
rawLastModDate,
|
|
5221
|
+
rawLastAccessDate,
|
|
5222
|
+
rawCreationDate
|
|
5223
|
+
});
|
|
5224
|
+
const lastModDate = getDateNTFS(rawLastModDate);
|
|
5225
|
+
const lastAccessDate = getDateNTFS(rawLastAccessDate);
|
|
5226
|
+
const creationDate = getDateNTFS(rawCreationDate);
|
|
5227
|
+
const extraFieldData = { lastModDate, lastAccessDate, creationDate };
|
|
5228
|
+
Object.assign(extraFieldNTFS, extraFieldData);
|
|
5229
|
+
Object.assign(directory, extraFieldData);
|
|
5205
5230
|
}
|
|
5206
5231
|
}
|
|
5207
5232
|
|
|
5233
|
+
function readExtraFieldUnixDates(extraField, directory) {
|
|
5234
|
+
if (extraField.data.length < 8) {
|
|
5235
|
+
return;
|
|
5236
|
+
}
|
|
5237
|
+
const extraFieldView = getDataView(extraField.data);
|
|
5238
|
+
const lastAccessDate = new Date(getUint32(extraFieldView, 0) * 1000);
|
|
5239
|
+
const lastModDate = new Date(getUint32(extraFieldView, 4) * 1000);
|
|
5240
|
+
const extraFieldData = { lastAccessDate, lastModDate };
|
|
5241
|
+
if (extraField.data.length >= 12) {
|
|
5242
|
+
extraFieldData.uid = getUint16(extraFieldView, 8);
|
|
5243
|
+
extraFieldData.gid = getUint16(extraFieldView, 10);
|
|
5244
|
+
}
|
|
5245
|
+
Object.assign(extraField, extraFieldData);
|
|
5246
|
+
Object.assign(directory, extraFieldData);
|
|
5247
|
+
}
|
|
5248
|
+
|
|
5208
5249
|
function readExtraFieldUnix(extraField, directory, isInfoZip) {
|
|
5209
5250
|
try {
|
|
5210
5251
|
const view = getDataView(extraField.data);
|
|
@@ -5283,7 +5324,7 @@
|
|
|
5283
5324
|
fileEntry,
|
|
5284
5325
|
index,
|
|
5285
5326
|
offset,
|
|
5286
|
-
|
|
5327
|
+
crc32,
|
|
5287
5328
|
compressedSize,
|
|
5288
5329
|
uncompressedSize,
|
|
5289
5330
|
dataOffset,
|
|
@@ -5304,7 +5345,7 @@
|
|
|
5304
5345
|
const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
|
|
5305
5346
|
getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
|
|
5306
5347
|
if (dataDescriptorSignature) {
|
|
5307
|
-
const
|
|
5348
|
+
const readCrc32 = getUint32(getDataView(dataDescriptorArray), 4);
|
|
5308
5349
|
let readCompressedSize;
|
|
5309
5350
|
let readUncompressedSize;
|
|
5310
5351
|
if (extraFieldZip64) {
|
|
@@ -5314,8 +5355,8 @@
|
|
|
5314
5355
|
readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
|
|
5315
5356
|
readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
|
|
5316
5357
|
}
|
|
5317
|
-
const
|
|
5318
|
-
if (
|
|
5358
|
+
const matchCrc32 = (fileEntry.encrypted && !fileEntry.zipCrypto) || readCrc32 == crc32;
|
|
5359
|
+
if (matchCrc32 &&
|
|
5319
5360
|
readCompressedSize == compressedSize &&
|
|
5320
5361
|
readUncompressedSize == uncompressedSize) {
|
|
5321
5362
|
dataDescriptorLength += DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH;
|
|
@@ -5484,11 +5525,11 @@
|
|
|
5484
5525
|
throwAmbiguousArchive("mismatched local file header (compression method)");
|
|
5485
5526
|
}
|
|
5486
5527
|
if (!localDirectory.bitFlag.dataDescriptor &&
|
|
5487
|
-
(localDirectory.
|
|
5488
|
-
(localDirectory.
|
|
5528
|
+
(localDirectory.crc32 || localDirectory.compressedSize || localDirectory.uncompressedSize) &&
|
|
5529
|
+
(localDirectory.crc32 != zipEntry.crc32 ||
|
|
5489
5530
|
localDirectory.compressedSize != zipEntry.compressedSize ||
|
|
5490
5531
|
localDirectory.uncompressedSize != zipEntry.uncompressedSize)) {
|
|
5491
|
-
throwAmbiguousArchive("mismatched local file header (
|
|
5532
|
+
throwAmbiguousArchive("mismatched local file header (crc32 or sizes)");
|
|
5492
5533
|
}
|
|
5493
5534
|
}
|
|
5494
5535
|
|
|
@@ -5504,11 +5545,7 @@
|
|
|
5504
5545
|
|
|
5505
5546
|
function getDate(timeRaw) {
|
|
5506
5547
|
const date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & MAX_16_BITS;
|
|
5507
|
-
|
|
5508
|
-
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
5509
|
-
} catch {
|
|
5510
|
-
// ignored
|
|
5511
|
-
}
|
|
5548
|
+
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0);
|
|
5512
5549
|
}
|
|
5513
5550
|
|
|
5514
5551
|
function getDateNTFS(timeRaw) {
|
|
@@ -5541,7 +5578,9 @@
|
|
|
5541
5578
|
ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
|
|
5542
5579
|
ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
|
|
5543
5580
|
ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
|
|
5581
|
+
ERR_INVALID_AUTHENTICATION_CODE: ERR_INVALID_AUTHENTICATION_CODE,
|
|
5544
5582
|
ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
|
|
5583
|
+
ERR_INVALID_CRC32: ERR_INVALID_CRC32,
|
|
5545
5584
|
ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
|
|
5546
5585
|
ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
|
|
5547
5586
|
ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
|
|
@@ -5595,6 +5634,8 @@
|
|
|
5595
5634
|
const ERR_UNSUPPORTED_COMPRESSION = "Compression method not supported";
|
|
5596
5635
|
const MIN_UNIX_TIME = -2147483648;
|
|
5597
5636
|
const MAX_UNIX_TIME = 2147483647;
|
|
5637
|
+
const MIN_NTFS_TIME = BigInt(0);
|
|
5638
|
+
const MAX_NTFS_TIME = BigInt("0x7fffffffffffffff");
|
|
5598
5639
|
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (set the 'zip64' option to 'true')";
|
|
5599
5640
|
const ERR_UNDEFINED_UNCOMPRESSED_SIZE = "Undefined uncompressed size";
|
|
5600
5641
|
const ERR_UNDEFINED_READER = "Undefined reader";
|
|
@@ -5608,6 +5649,8 @@
|
|
|
5608
5649
|
const ERR_INVALID_MSDOS_DATA = "Invalid msdosAttributes (must be an object with boolean flags)";
|
|
5609
5650
|
|
|
5610
5651
|
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
5652
|
+
const EXTRAFIELD_OFFSET_AES_VENDOR_VERSION = 4;
|
|
5653
|
+
const VENDOR_VERSION_AE_1 = 1;
|
|
5611
5654
|
const INFOZIP_EXTRA_FIELD_TYPE = "infozip";
|
|
5612
5655
|
const UNIX_EXTRA_FIELD_TYPE = "unix";
|
|
5613
5656
|
|
|
@@ -5702,9 +5745,9 @@
|
|
|
5702
5745
|
zip64UncompressedSize,
|
|
5703
5746
|
extraFieldLength
|
|
5704
5747
|
});
|
|
5705
|
-
const {
|
|
5706
|
-
if (
|
|
5707
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE,
|
|
5748
|
+
const { crc32 } = entry;
|
|
5749
|
+
if (crc32 !== UNDEFINED_VALUE) {
|
|
5750
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
5708
5751
|
}
|
|
5709
5752
|
Object.assign(entry, {
|
|
5710
5753
|
zip64UncompressedSize,
|
|
@@ -5889,6 +5932,7 @@
|
|
|
5889
5932
|
internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
|
|
5890
5933
|
externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
|
|
5891
5934
|
signature: options[PROPERTY_NAME_SIGNATURE],
|
|
5935
|
+
crc32: options.crc32 === UNDEFINED_VALUE ? options[PROPERTY_NAME_SIGNATURE] : options.crc32,
|
|
5892
5936
|
offset: zipWriter.offset - diskOffset,
|
|
5893
5937
|
diskNumberStart: diskNumber
|
|
5894
5938
|
});
|
|
@@ -6105,27 +6149,8 @@
|
|
|
6105
6149
|
if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
|
|
6106
6150
|
throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
|
|
6107
6151
|
}
|
|
6108
|
-
|
|
6109
|
-
const
|
|
6110
|
-
if (extraField) {
|
|
6111
|
-
let extraFieldSize = 0;
|
|
6112
|
-
let offset = 0;
|
|
6113
|
-
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
6114
|
-
rawExtraField = new Uint8Array(extraFieldSize);
|
|
6115
|
-
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6116
|
-
extraField.forEach((data, type) => {
|
|
6117
|
-
if (type > MAX_16_BITS) {
|
|
6118
|
-
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
6119
|
-
}
|
|
6120
|
-
if (getLength(data) > MAX_16_BITS) {
|
|
6121
|
-
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6122
|
-
}
|
|
6123
|
-
setUint16(rawExtraFieldView, offset, type);
|
|
6124
|
-
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
6125
|
-
arraySet(rawExtraField, data, offset + 4);
|
|
6126
|
-
offset += 4 + getLength(data);
|
|
6127
|
-
});
|
|
6128
|
-
}
|
|
6152
|
+
const rawExtraField = serializeExtraField(options[PROPERTY_NAME_EXTRA_FIELD]);
|
|
6153
|
+
const rawLocalExtraField = serializeExtraField(options[OPTION_LOCAL_EXTRA_FIELD]);
|
|
6129
6154
|
return {
|
|
6130
6155
|
comment,
|
|
6131
6156
|
resolvedOptions: {
|
|
@@ -6159,11 +6184,36 @@
|
|
|
6159
6184
|
useCompressionStream,
|
|
6160
6185
|
dataDescriptor,
|
|
6161
6186
|
zip64,
|
|
6162
|
-
rawExtraField
|
|
6187
|
+
rawExtraField,
|
|
6188
|
+
rawLocalExtraField
|
|
6163
6189
|
}
|
|
6164
6190
|
};
|
|
6165
6191
|
}
|
|
6166
6192
|
|
|
6193
|
+
function serializeExtraField(extraField) {
|
|
6194
|
+
if (!extraField) {
|
|
6195
|
+
return EMPTY_UINT8_ARRAY;
|
|
6196
|
+
}
|
|
6197
|
+
let extraFieldSize = 0;
|
|
6198
|
+
let offset = 0;
|
|
6199
|
+
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
6200
|
+
const rawExtraField = new Uint8Array(extraFieldSize);
|
|
6201
|
+
const rawExtraFieldView = getDataView(rawExtraField);
|
|
6202
|
+
extraField.forEach((data, type) => {
|
|
6203
|
+
if (type > MAX_16_BITS) {
|
|
6204
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
6205
|
+
}
|
|
6206
|
+
if (getLength(data) > MAX_16_BITS) {
|
|
6207
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6208
|
+
}
|
|
6209
|
+
setUint16(rawExtraFieldView, offset, type);
|
|
6210
|
+
setUint16(rawExtraFieldView, offset + 2, getLength(data));
|
|
6211
|
+
arraySet(rawExtraField, data, offset + 4);
|
|
6212
|
+
offset += 4 + getLength(data);
|
|
6213
|
+
});
|
|
6214
|
+
return rawExtraField;
|
|
6215
|
+
}
|
|
6216
|
+
|
|
6167
6217
|
async function resolveSizes(zipWriter, reader, { resolvedOptions: metadata }, options) {
|
|
6168
6218
|
const { passThrough, zipCrypto, password, rawPassword, encryptionStrength } = metadata;
|
|
6169
6219
|
let { dataDescriptor, zip64, level, compressionMethod } = metadata;
|
|
@@ -6488,7 +6538,7 @@
|
|
|
6488
6538
|
msdosAttributes
|
|
6489
6539
|
};
|
|
6490
6540
|
let {
|
|
6491
|
-
|
|
6541
|
+
crc32,
|
|
6492
6542
|
uncompressedSize
|
|
6493
6543
|
} = options;
|
|
6494
6544
|
let compressedSize = 0;
|
|
@@ -6508,7 +6558,7 @@
|
|
|
6508
6558
|
encryptionStrength,
|
|
6509
6559
|
zipCrypto: encrypted && zipCrypto,
|
|
6510
6560
|
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & MAX_8_BITS,
|
|
6511
|
-
|
|
6561
|
+
computeCrc32: !passThrough,
|
|
6512
6562
|
compressed: compressed && !passThrough,
|
|
6513
6563
|
encrypted: encrypted && !passThrough,
|
|
6514
6564
|
useWebWorkers,
|
|
@@ -6527,7 +6577,9 @@
|
|
|
6527
6577
|
writer.size += compressedSize;
|
|
6528
6578
|
if (!passThrough) {
|
|
6529
6579
|
uncompressedSize = result.inputSize;
|
|
6530
|
-
|
|
6580
|
+
if (!encrypted || zipCrypto) {
|
|
6581
|
+
crc32 = result.crc32;
|
|
6582
|
+
}
|
|
6531
6583
|
}
|
|
6532
6584
|
if ((!zip64CompressedSize && compressedSize >= MAX_32_BITS) ||
|
|
6533
6585
|
(!zip64UncompressedSize && uncompressedSize >= MAX_32_BITS)) {
|
|
@@ -6542,7 +6594,7 @@
|
|
|
6542
6594
|
|
|
6543
6595
|
}
|
|
6544
6596
|
setEntryInfo({
|
|
6545
|
-
|
|
6597
|
+
crc32,
|
|
6546
6598
|
compressedSize,
|
|
6547
6599
|
uncompressedSize,
|
|
6548
6600
|
headerInfo,
|
|
@@ -6565,7 +6617,8 @@
|
|
|
6565
6617
|
version,
|
|
6566
6618
|
headerArray,
|
|
6567
6619
|
headerView,
|
|
6568
|
-
signature,
|
|
6620
|
+
signature: crc32,
|
|
6621
|
+
crc32: encrypted && !zipCrypto && !passThrough ? UNDEFINED_VALUE : crc32,
|
|
6569
6622
|
extraFieldExtendedTimestampFlag,
|
|
6570
6623
|
zip64UncompressedSize,
|
|
6571
6624
|
zip64CompressedSize
|
|
@@ -6586,6 +6639,7 @@
|
|
|
6586
6639
|
dataDescriptor,
|
|
6587
6640
|
directory,
|
|
6588
6641
|
rawExtraField,
|
|
6642
|
+
rawLocalExtraField,
|
|
6589
6643
|
encryptionStrength,
|
|
6590
6644
|
extendedTimestamp,
|
|
6591
6645
|
ntfsTimestamp,
|
|
@@ -6593,7 +6647,8 @@
|
|
|
6593
6647
|
encrypted,
|
|
6594
6648
|
zip64UncompressedSize,
|
|
6595
6649
|
zip64CompressedSize,
|
|
6596
|
-
uncompressedSize
|
|
6650
|
+
uncompressedSize,
|
|
6651
|
+
crc32
|
|
6597
6652
|
} = options;
|
|
6598
6653
|
let { version, compressionMethod } = options;
|
|
6599
6654
|
const compressed = !directory && (compressionMethod === UNDEFINED_VALUE
|
|
@@ -6666,8 +6721,8 @@
|
|
|
6666
6721
|
extraFieldNTFS.uint16(EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
6667
6722
|
extraFieldNTFS.uint16(24);
|
|
6668
6723
|
extraFieldNTFS.uint64(lastModTimeNTFS);
|
|
6669
|
-
extraFieldNTFS.uint64(getTimeNTFS(lastAccessDate)
|
|
6670
|
-
extraFieldNTFS.uint64(getTimeNTFS(creationDate)
|
|
6724
|
+
extraFieldNTFS.uint64(lastAccessDate ? getTimeNTFS(lastAccessDate) : lastModTimeNTFS);
|
|
6725
|
+
extraFieldNTFS.uint64(creationDate ? getTimeNTFS(creationDate) : lastModTimeNTFS);
|
|
6671
6726
|
rawExtraFieldNTFS = extraFieldNTFS.array;
|
|
6672
6727
|
} catch {
|
|
6673
6728
|
rawExtraFieldNTFS = EMPTY_UINT8_ARRAY;
|
|
@@ -6719,15 +6774,18 @@
|
|
|
6719
6774
|
}
|
|
6720
6775
|
if (encrypted && !zipCrypto) {
|
|
6721
6776
|
version = version > VERSION_AES ? version : VERSION_AES;
|
|
6777
|
+
if (passThrough && crc32 !== UNDEFINED_VALUE) {
|
|
6778
|
+
rawExtraFieldAES[EXTRAFIELD_OFFSET_AES_VENDOR_VERSION] = VENDOR_VERSION_AE_1;
|
|
6779
|
+
}
|
|
6722
6780
|
rawExtraFieldAES[9] = compressionMethod;
|
|
6723
6781
|
compressionMethod = COMPRESSION_METHOD_AES;
|
|
6724
6782
|
}
|
|
6725
6783
|
const localExtraFieldZip64Length = writeLocalExtraFieldZip64 ? getLength(rawLocalExtraFieldZip64) : 0;
|
|
6726
|
-
const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
|
|
6784
|
+
const extraFieldLength = localExtraFieldZip64Length + getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField, rawLocalExtraField);
|
|
6727
6785
|
if (extraFieldLength > MAX_16_BITS) {
|
|
6728
6786
|
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
6729
6787
|
}
|
|
6730
|
-
const dosLastModDate = new Date(Math.ceil(lastModDate.getTime() /
|
|
6788
|
+
const dosLastModDate = new Date(Math.ceil(Math.floor(lastModDate.getTime() / 1000) / 2) * 2000);
|
|
6731
6789
|
const {
|
|
6732
6790
|
headerArray,
|
|
6733
6791
|
headerView,
|
|
@@ -6757,6 +6815,7 @@
|
|
|
6757
6815
|
localHeader.bytes(rawExtraFieldNTFS);
|
|
6758
6816
|
localHeader.bytes(rawExtraFieldUnix);
|
|
6759
6817
|
localHeader.bytes(rawExtraField);
|
|
6818
|
+
localHeader.bytes(rawLocalExtraField);
|
|
6760
6819
|
if (dataDescriptor) {
|
|
6761
6820
|
if (!zip64CompressedSize) {
|
|
6762
6821
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, 0);
|
|
@@ -6875,7 +6934,7 @@
|
|
|
6875
6934
|
}
|
|
6876
6935
|
|
|
6877
6936
|
function setEntryInfo({
|
|
6878
|
-
|
|
6937
|
+
crc32,
|
|
6879
6938
|
compressedSize,
|
|
6880
6939
|
uncompressedSize,
|
|
6881
6940
|
headerInfo,
|
|
@@ -6883,6 +6942,7 @@
|
|
|
6883
6942
|
}, {
|
|
6884
6943
|
zip64,
|
|
6885
6944
|
zipCrypto,
|
|
6945
|
+
passThrough,
|
|
6886
6946
|
dataDescriptor
|
|
6887
6947
|
}) {
|
|
6888
6948
|
const {
|
|
@@ -6893,10 +6953,10 @@
|
|
|
6893
6953
|
dataDescriptorView,
|
|
6894
6954
|
dataDescriptorOffset
|
|
6895
6955
|
} = dataDescriptorInfo;
|
|
6896
|
-
if ((!encrypted || zipCrypto) &&
|
|
6897
|
-
setUint32(headerView, HEADER_OFFSET_SIGNATURE,
|
|
6956
|
+
if ((!encrypted || zipCrypto || passThrough) && crc32 !== UNDEFINED_VALUE) {
|
|
6957
|
+
setUint32(headerView, HEADER_OFFSET_SIGNATURE, crc32);
|
|
6898
6958
|
if (dataDescriptor) {
|
|
6899
|
-
setUint32(dataDescriptorView, dataDescriptorOffset,
|
|
6959
|
+
setUint32(dataDescriptorView, dataDescriptorOffset, crc32);
|
|
6900
6960
|
}
|
|
6901
6961
|
}
|
|
6902
6962
|
if (zip64) {
|
|
@@ -6919,15 +6979,15 @@
|
|
|
6919
6979
|
encrypted,
|
|
6920
6980
|
zip64,
|
|
6921
6981
|
localExtraFieldZip64Length,
|
|
6922
|
-
|
|
6982
|
+
crc32,
|
|
6923
6983
|
compressedSize,
|
|
6924
6984
|
uncompressedSize,
|
|
6925
6985
|
zip64UncompressedSize,
|
|
6926
6986
|
zip64CompressedSize
|
|
6927
|
-
}, localHeaderView, { dataDescriptor }) {
|
|
6987
|
+
}, localHeaderView, { dataDescriptor, passThrough }) {
|
|
6928
6988
|
if (!dataDescriptor) {
|
|
6929
|
-
if (!encrypted) {
|
|
6930
|
-
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET,
|
|
6989
|
+
if (!encrypted || (passThrough && crc32 !== UNDEFINED_VALUE)) {
|
|
6990
|
+
setUint32(localHeaderView, HEADER_OFFSET_SIGNATURE + LOCAL_HEADER_COMMON_OFFSET, crc32);
|
|
6931
6991
|
}
|
|
6932
6992
|
if (!zip64CompressedSize) {
|
|
6933
6993
|
setUint32(localHeaderView, HEADER_OFFSET_COMPRESSED_SIZE + LOCAL_HEADER_COMMON_OFFSET, compressedSize);
|
|
@@ -7236,7 +7296,8 @@
|
|
|
7236
7296
|
|
|
7237
7297
|
function getTimeNTFS(date) {
|
|
7238
7298
|
if (date) {
|
|
7239
|
-
|
|
7299
|
+
const timeNTFS = ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
|
|
7300
|
+
return timeNTFS < MIN_NTFS_TIME ? MIN_NTFS_TIME : timeNTFS > MAX_NTFS_TIME ? MAX_NTFS_TIME : timeNTFS;
|
|
7240
7301
|
}
|
|
7241
7302
|
}
|
|
7242
7303
|
|
|
@@ -7841,10 +7902,12 @@
|
|
|
7841
7902
|
exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
|
|
7842
7903
|
exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
|
|
7843
7904
|
exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
|
|
7905
|
+
exports.ERR_INVALID_AUTHENTICATION_CODE = ERR_INVALID_AUTHENTICATION_CODE;
|
|
7844
7906
|
exports.ERR_INVALID_CODEC_DEFINITION = ERR_INVALID_CODEC_DEFINITION;
|
|
7845
7907
|
exports.ERR_INVALID_CODEC_MODULE = ERR_INVALID_CODEC_MODULE;
|
|
7846
7908
|
exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
|
|
7847
7909
|
exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
|
|
7910
|
+
exports.ERR_INVALID_CRC32 = ERR_INVALID_CRC32;
|
|
7848
7911
|
exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
|
|
7849
7912
|
exports.ERR_INVALID_ENTRY_COMMENT = ERR_INVALID_ENTRY_COMMENT;
|
|
7850
7913
|
exports.ERR_INVALID_ENTRY_NAME = ERR_INVALID_ENTRY_NAME;
|