@zip.js/zip.js 2.14.1 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BENCHMARKS.md +21 -11
- package/deno.json +1 -1
- package/dist/zip-core-external.js +217 -98
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +217 -98
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +217 -98
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +217 -98
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +217 -98
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +219 -100
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +219 -100
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +219 -100
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +219 -100
- 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 +219 -100
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +219 -100
- package/index-native.min.js +1 -1
- package/index.cjs +219 -100
- package/index.d.cts +46 -13
- package/index.d.ts +46 -13
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +35 -19
- package/lib/core/codec-worker.js +4 -2
- package/lib/core/io.js +3 -2
- package/lib/core/streams/zip-entry-stream.js +151 -66
- package/lib/core/util/decode-text.js +15 -1
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-reader.js +12 -10
- package/lib/core/zlib-streams-inline.js +1 -1
- package/package.json +1 -1
package/dist/zip-core.js
CHANGED
|
@@ -1858,7 +1858,6 @@
|
|
|
1858
1858
|
const GZIP_HEADER_LENGTH = 10;
|
|
1859
1859
|
const GZIP_TRAILER_LENGTH = 8;
|
|
1860
1860
|
const GZIP_HEADER_BYTES = [0x1f, 0x8b, 0x08];
|
|
1861
|
-
const GZIP_OUTPUT_STALL_TIMEOUT = 5000;
|
|
1862
1861
|
|
|
1863
1862
|
class DeflateStream extends TransformStream {
|
|
1864
1863
|
|
|
@@ -1869,8 +1868,8 @@
|
|
|
1869
1868
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
1870
1869
|
let readable = super.readable;
|
|
1871
1870
|
const codecStreams = format && getCodecStreams(format);
|
|
1872
|
-
const
|
|
1873
|
-
|
|
1871
|
+
const GzipCompressionStream = getGzipCodecStream(useCompressionStream, CompressionStream, CompressionStreamFallback);
|
|
1872
|
+
const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) && Boolean(GzipCompressionStream);
|
|
1874
1873
|
if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
|
|
1875
1874
|
crc32Stream = new Crc32Stream();
|
|
1876
1875
|
readable = pipeThrough(readable, crc32Stream);
|
|
@@ -1880,12 +1879,15 @@
|
|
|
1880
1879
|
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod, uncompressedSize: inputSize }));
|
|
1881
1880
|
} else if (useGzipCrc32) {
|
|
1882
1881
|
gzipCrc32Stream = new GzipToRawDeflateStream();
|
|
1883
|
-
readable = pipeThroughBackpressured(readable, new
|
|
1882
|
+
readable = pipeThroughBackpressured(readable, new GzipCompressionStream(FORMAT_GZIP, { level, chunkSize }));
|
|
1884
1883
|
readable = pipeThrough(readable, gzipCrc32Stream);
|
|
1885
1884
|
} else {
|
|
1886
1885
|
try {
|
|
1887
1886
|
readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
|
|
1888
1887
|
} catch (error) {
|
|
1888
|
+
if (!useCompressionStream && CompressionStreamFallback) {
|
|
1889
|
+
throw error;
|
|
1890
|
+
}
|
|
1889
1891
|
let gzipStream;
|
|
1890
1892
|
try {
|
|
1891
1893
|
gzipStream = new CompressionStream(FORMAT_GZIP);
|
|
@@ -1954,82 +1956,144 @@
|
|
|
1954
1956
|
}
|
|
1955
1957
|
}
|
|
1956
1958
|
|
|
1957
|
-
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
|
|
1958
|
-
const
|
|
1959
|
+
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
|
|
1960
|
+
const writer = gzipStream.writable.getWriter();
|
|
1961
|
+
const reader = gzipStream.readable.getReader();
|
|
1962
|
+
const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
|
|
1959
1963
|
let outputLength = 0;
|
|
1960
1964
|
let inputDone = false;
|
|
1961
|
-
let
|
|
1965
|
+
let trailerWritten = false;
|
|
1966
|
+
let idleCheckArmed = false;
|
|
1967
|
+
let readCount = 0;
|
|
1968
|
+
let readPending = false;
|
|
1962
1969
|
let resolveTrailerReady, rejectTrailerReady;
|
|
1963
1970
|
const trailerReady = new Promise((resolve, reject) => {
|
|
1964
1971
|
resolveTrailerReady = resolve;
|
|
1965
1972
|
rejectTrailerReady = reject;
|
|
1966
1973
|
});
|
|
1967
1974
|
trailerReady.catch(() => { });
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1975
|
+
pump();
|
|
1976
|
+
return new ReadableStream({
|
|
1977
|
+
async pull(controller) {
|
|
1978
|
+
let result;
|
|
1979
|
+
try {
|
|
1980
|
+
result = await read();
|
|
1981
|
+
} catch (error) {
|
|
1982
|
+
throw trailerWritten ? getTrailerError(error) : error;
|
|
1983
|
+
}
|
|
1984
|
+
const { value, done } = result;
|
|
1985
|
+
if (done) {
|
|
1986
|
+
controller.close();
|
|
1987
|
+
} else {
|
|
1988
|
+
outputLength += value.length;
|
|
1989
|
+
if (outputLength > outputSize) {
|
|
1990
|
+
const error = new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
1991
|
+
rejectTrailerReady(error);
|
|
1992
|
+
await cancel(reader, error);
|
|
1993
|
+
throw error;
|
|
1994
|
+
}
|
|
1995
|
+
if (outputCrc32) {
|
|
1996
|
+
outputCrc32.append(value);
|
|
1997
|
+
}
|
|
1998
|
+
controller.enqueue(value);
|
|
1999
|
+
}
|
|
2000
|
+
},
|
|
2001
|
+
cancel(reason) {
|
|
2002
|
+
rejectTrailerReady(reason);
|
|
2003
|
+
return reader.cancel(reason);
|
|
2004
|
+
}
|
|
2005
|
+
});
|
|
2006
|
+
|
|
2007
|
+
async function pump() {
|
|
2008
|
+
const inputReader = readable.getReader();
|
|
2009
|
+
try {
|
|
1973
2010
|
const header = new Uint8Array(GZIP_HEADER_LENGTH);
|
|
1974
2011
|
header.set(GZIP_HEADER_BYTES);
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2012
|
+
await writer.write(header);
|
|
2013
|
+
for (; ;) {
|
|
2014
|
+
await writer.ready;
|
|
2015
|
+
const { value, done } = await inputReader.read();
|
|
2016
|
+
if (done) {
|
|
2017
|
+
break;
|
|
2018
|
+
}
|
|
2019
|
+
await writer.write(value);
|
|
2020
|
+
}
|
|
1981
2021
|
inputDone = true;
|
|
1982
|
-
|
|
1983
|
-
|
|
2022
|
+
if (outputCrc32) {
|
|
2023
|
+
if (readPending) {
|
|
2024
|
+
armIdleCheck();
|
|
2025
|
+
}
|
|
1984
2026
|
await trailerReady;
|
|
1985
|
-
} finally {
|
|
1986
|
-
stopWatchdog();
|
|
1987
2027
|
}
|
|
1988
2028
|
const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
|
|
1989
2029
|
const dataView = getDataView(trailer);
|
|
1990
|
-
dataView.setUint32(0,
|
|
2030
|
+
dataView.setUint32(0, outputCrc32 ? outputCrc32.get() : crc32, true);
|
|
1991
2031
|
dataView.setUint32(4, outputSize, true);
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
2032
|
+
trailerWritten = true;
|
|
2033
|
+
await writer.write(trailer);
|
|
2034
|
+
await writer.close();
|
|
2035
|
+
} catch (error) {
|
|
2036
|
+
await abort(writer, error);
|
|
2037
|
+
await cancel(inputReader, error);
|
|
1996
2038
|
}
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
}
|
|
2007
|
-
controller.enqueue(chunk);
|
|
2008
|
-
},
|
|
2009
|
-
cancel(reason) {
|
|
2010
|
-
rejectTrailerReady(reason);
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
function read() {
|
|
2042
|
+
readCount++;
|
|
2043
|
+
readPending = true;
|
|
2044
|
+
const result = reader.read();
|
|
2045
|
+
result.then(onReadSettled, onReadSettled);
|
|
2046
|
+
if (inputDone && outputCrc32) {
|
|
2047
|
+
armIdleCheck();
|
|
2011
2048
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
readable = pipeThroughBackpressured(readable, gzipStream);
|
|
2015
|
-
return pipeThrough(readable, outputStream);
|
|
2049
|
+
return result;
|
|
2050
|
+
}
|
|
2016
2051
|
|
|
2017
|
-
function
|
|
2018
|
-
|
|
2019
|
-
|
|
2052
|
+
function onReadSettled() {
|
|
2053
|
+
readPending = false;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
async function armIdleCheck() {
|
|
2057
|
+
if (!idleCheckArmed) {
|
|
2058
|
+
idleCheckArmed = true;
|
|
2059
|
+
const count = readCount;
|
|
2060
|
+
await nextTask();
|
|
2061
|
+
idleCheckArmed = false;
|
|
2062
|
+
if (readPending) {
|
|
2063
|
+
if (readCount == count) {
|
|
2064
|
+
resolveTrailerReady();
|
|
2065
|
+
} else {
|
|
2066
|
+
armIdleCheck();
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2020
2070
|
}
|
|
2021
2071
|
|
|
2022
|
-
function
|
|
2023
|
-
|
|
2072
|
+
function getTrailerError(error) {
|
|
2073
|
+
const trailerError = new Error(outputLength == outputSize ? ERR_INVALID_CRC32 : ERR_INVALID_UNCOMPRESSED_SIZE);
|
|
2074
|
+
trailerError.cause = error;
|
|
2075
|
+
return trailerError;
|
|
2024
2076
|
}
|
|
2025
2077
|
}
|
|
2026
2078
|
|
|
2079
|
+
function nextTask() {
|
|
2080
|
+
return new Promise(resolve => {
|
|
2081
|
+
const { port1, port2 } = new MessageChannel();
|
|
2082
|
+
port2.onmessage = () => {
|
|
2083
|
+
port1.close();
|
|
2084
|
+
port2.close();
|
|
2085
|
+
resolve();
|
|
2086
|
+
};
|
|
2087
|
+
port1.postMessage(UNDEFINED_VALUE);
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2027
2091
|
class InflateStream extends TransformStream {
|
|
2028
2092
|
|
|
2029
2093
|
constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
|
|
2030
2094
|
super({});
|
|
2031
2095
|
const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
|
|
2032
|
-
let crc32Stream, decryptionStream;
|
|
2096
|
+
let crc32Stream, decryptionStream, gzipCrc32;
|
|
2033
2097
|
let readable = super.readable;
|
|
2034
2098
|
if (encrypted) {
|
|
2035
2099
|
if (zipCrypto) {
|
|
@@ -2044,31 +2108,44 @@
|
|
|
2044
2108
|
if (codecStreams) {
|
|
2045
2109
|
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
|
|
2046
2110
|
} else {
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
if (deflate64 || outputSize === UNDEFINED_VALUE) {
|
|
2051
|
-
throw error;
|
|
2052
|
-
}
|
|
2053
|
-
let gzipStream;
|
|
2111
|
+
let gzipStream;
|
|
2112
|
+
const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
|
|
2113
|
+
if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
|
|
2054
2114
|
try {
|
|
2055
|
-
gzipStream = new
|
|
2115
|
+
gzipStream = new GzipDecompressionStream(FORMAT_GZIP, { chunkSize });
|
|
2056
2116
|
} catch {
|
|
2057
|
-
|
|
2117
|
+
gzipStream = UNDEFINED_VALUE;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
if (!gzipStream) {
|
|
2121
|
+
try {
|
|
2122
|
+
readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
|
|
2123
|
+
} catch (error) {
|
|
2124
|
+
if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
|
|
2125
|
+
throw error;
|
|
2126
|
+
}
|
|
2127
|
+
try {
|
|
2128
|
+
gzipStream = new DecompressionStream(FORMAT_GZIP);
|
|
2129
|
+
} catch {
|
|
2130
|
+
throw error;
|
|
2131
|
+
}
|
|
2058
2132
|
}
|
|
2059
|
-
|
|
2133
|
+
}
|
|
2134
|
+
if (gzipStream) {
|
|
2135
|
+
gzipCrc32 = true;
|
|
2136
|
+
readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32);
|
|
2060
2137
|
}
|
|
2061
2138
|
}
|
|
2062
2139
|
readable = mapInflateStreamError(readable);
|
|
2063
2140
|
}
|
|
2064
|
-
if (checkCrc32) {
|
|
2141
|
+
if (checkCrc32 && !gzipCrc32) {
|
|
2065
2142
|
crc32Stream = new Crc32Stream();
|
|
2066
2143
|
readable = pipeThrough(readable, crc32Stream);
|
|
2067
2144
|
}
|
|
2068
2145
|
setReadable(this, readable, () => {
|
|
2069
|
-
if (
|
|
2070
|
-
const
|
|
2071
|
-
if (crc32 !=
|
|
2146
|
+
if (crc32Stream) {
|
|
2147
|
+
const computedCrc32 = new DataView(crc32Stream.value.buffer).getUint32(0, false);
|
|
2148
|
+
if (crc32 != computedCrc32) {
|
|
2072
2149
|
throw new Error(ERR_INVALID_CRC32);
|
|
2073
2150
|
}
|
|
2074
2151
|
}
|
|
@@ -2124,6 +2201,14 @@
|
|
|
2124
2201
|
return new CodecStreamClass(format, options);
|
|
2125
2202
|
}
|
|
2126
2203
|
|
|
2204
|
+
function getGzipCodecStream(useCompressionStream, CodecStreamNative, CodecStreamFallback) {
|
|
2205
|
+
if (useCompressionStream && CodecStreamNative) {
|
|
2206
|
+
return CodecStreamNative;
|
|
2207
|
+
} else if (CodecStreamFallback && CodecStreamFallback.requiresModule) {
|
|
2208
|
+
return CodecStreamFallback;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2127
2212
|
function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
|
|
2128
2213
|
const Stream = useCompressionStream && CompressionStreamNative ?
|
|
2129
2214
|
CompressionStreamNative :
|
|
@@ -2492,10 +2577,12 @@
|
|
|
2492
2577
|
workerData.terminated = true;
|
|
2493
2578
|
worker.terminate();
|
|
2494
2579
|
}
|
|
2495
|
-
terminateResolvers.forEach(resolve => resolve());
|
|
2496
2580
|
}
|
|
2497
2581
|
workerData.busy = false;
|
|
2498
|
-
onTaskFinished(workerData);
|
|
2582
|
+
const pendingTasks = onTaskFinished(workerData);
|
|
2583
|
+
if (terminateResolvers) {
|
|
2584
|
+
terminateResolvers.forEach(resolve => resolve(pendingTasks));
|
|
2585
|
+
}
|
|
2499
2586
|
}
|
|
2500
2587
|
}
|
|
2501
2588
|
});
|
|
@@ -3180,7 +3267,10 @@
|
|
|
3180
3267
|
|
|
3181
3268
|
function onTaskFinished(workerData) {
|
|
3182
3269
|
clearStarvationTimeout();
|
|
3183
|
-
if (
|
|
3270
|
+
if (workerData.terminated) {
|
|
3271
|
+
workerData.terminated = false;
|
|
3272
|
+
return runPendingRequestsInline();
|
|
3273
|
+
} else if (pendingRequests.length) {
|
|
3184
3274
|
const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
|
|
3185
3275
|
resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
|
|
3186
3276
|
armStarvationTimeout();
|
|
@@ -3218,12 +3308,26 @@
|
|
|
3218
3308
|
starvationTimeout = null;
|
|
3219
3309
|
if (pendingRequests.length) {
|
|
3220
3310
|
const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
|
|
3221
|
-
|
|
3222
|
-
resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
|
|
3311
|
+
resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), onInlineTaskFinished));
|
|
3223
3312
|
armStarvationTimeout();
|
|
3224
3313
|
}
|
|
3225
3314
|
}
|
|
3226
3315
|
|
|
3316
|
+
function runPendingRequestsInline() {
|
|
3317
|
+
const tasks = pendingRequests.splice(0).map(({ resolve, stream, workerOptions }) => new Promise(resolveTask => {
|
|
3318
|
+
resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), () => {
|
|
3319
|
+
onInlineTaskFinished();
|
|
3320
|
+
resolveTask();
|
|
3321
|
+
}));
|
|
3322
|
+
}));
|
|
3323
|
+
clearStarvationTimeout();
|
|
3324
|
+
return Promise.all(tasks);
|
|
3325
|
+
}
|
|
3326
|
+
|
|
3327
|
+
function getInlineWorkerOptions(workerOptions) {
|
|
3328
|
+
return Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3227
3331
|
function onInlineTaskFinished() {
|
|
3228
3332
|
clearStarvationTimeout();
|
|
3229
3333
|
armStarvationTimeout();
|
|
@@ -3233,18 +3337,14 @@
|
|
|
3233
3337
|
const { config } = workerOptions;
|
|
3234
3338
|
const { terminateWorkerTimeout } = config;
|
|
3235
3339
|
if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
// ignored
|
|
3245
|
-
}
|
|
3246
|
-
}, terminateWorkerTimeout);
|
|
3247
|
-
}
|
|
3340
|
+
workerData.terminateTimeout = setTimeout(async () => {
|
|
3341
|
+
pool = pool.filter(data => data != workerData);
|
|
3342
|
+
try {
|
|
3343
|
+
await workerData.terminate();
|
|
3344
|
+
} catch {
|
|
3345
|
+
// ignored
|
|
3346
|
+
}
|
|
3347
|
+
}, terminateWorkerTimeout);
|
|
3248
3348
|
}
|
|
3249
3349
|
}
|
|
3250
3350
|
|
|
@@ -3257,10 +3357,13 @@
|
|
|
3257
3357
|
}
|
|
3258
3358
|
|
|
3259
3359
|
async function terminateWorkers() {
|
|
3260
|
-
await Promise.allSettled(
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3360
|
+
await Promise.allSettled([
|
|
3361
|
+
runPendingRequestsInline(),
|
|
3362
|
+
...pool.map(workerData => {
|
|
3363
|
+
clearTerminateTimeout(workerData);
|
|
3364
|
+
return workerData.terminate();
|
|
3365
|
+
})
|
|
3366
|
+
]);
|
|
3264
3367
|
resetWebWorkerSupport();
|
|
3265
3368
|
}
|
|
3266
3369
|
|
|
@@ -3335,6 +3438,19 @@
|
|
|
3335
3438
|
return decode(value, encoding, true);
|
|
3336
3439
|
}
|
|
3337
3440
|
|
|
3441
|
+
function isUTF8Text(value) {
|
|
3442
|
+
if (value.some(byte => byte > 0x7f)) {
|
|
3443
|
+
try {
|
|
3444
|
+
new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
3445
|
+
return true;
|
|
3446
|
+
} catch {
|
|
3447
|
+
return false;
|
|
3448
|
+
}
|
|
3449
|
+
} else {
|
|
3450
|
+
return false;
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3338
3454
|
function decodeTextRemovingBOM(value, encoding) {
|
|
3339
3455
|
return decode(value, encoding, false);
|
|
3340
3456
|
}
|
|
@@ -3667,10 +3783,11 @@
|
|
|
3667
3783
|
|
|
3668
3784
|
createReadable(options) {
|
|
3669
3785
|
const reader = this;
|
|
3670
|
-
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
3786
|
+
const { useRangeHeader, forceRangeRequests, size, eocdCache } = reader;
|
|
3671
3787
|
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
3672
3788
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3673
|
-
|
|
3789
|
+
const cached = eocdCache && offset >= size - eocdCache.length;
|
|
3790
|
+
if (readSize > 0 && offset < size && !cached) {
|
|
3674
3791
|
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
3675
3792
|
}
|
|
3676
3793
|
}
|
|
@@ -4624,6 +4741,7 @@
|
|
|
4624
4741
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4625
4742
|
const MAX_KNOWN_VERSION = 63;
|
|
4626
4743
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4744
|
+
const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
|
|
4627
4745
|
const CHARSET_UTF8 = "utf-8";
|
|
4628
4746
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
4629
4747
|
const CHARSET_CP437 = "cp437";
|
|
@@ -4876,12 +4994,13 @@
|
|
|
4876
4994
|
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4877
4995
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4878
4996
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4879
|
-
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4880
4997
|
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4881
4998
|
const endOffset = commentOffset + commentLength;
|
|
4882
|
-
const
|
|
4883
|
-
const
|
|
4884
|
-
const
|
|
4999
|
+
const rawEntryData = new Uint8Array(directoryArray.subarray(filenameOffset, endOffset));
|
|
5000
|
+
const rawFilename = rawEntryData.subarray(0, fileEntry.filenameLength);
|
|
5001
|
+
const rawComment = rawEntryData.subarray(fileEntry.filenameLength + fileEntry.extraFieldLength);
|
|
5002
|
+
const filenameUTF8 = languageEncodingFlag || (!filenameEncoding && isUTF8Text(rawFilename));
|
|
5003
|
+
const commentUTF8 = languageEncodingFlag || (!commentEncoding && isUTF8Text(rawComment));
|
|
4885
5004
|
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4886
5005
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4887
5006
|
const msdosAttributes = {
|
|
@@ -4932,7 +5051,7 @@
|
|
|
4932
5051
|
rawFilename,
|
|
4933
5052
|
filenameUTF8,
|
|
4934
5053
|
commentUTF8,
|
|
4935
|
-
rawExtraField:
|
|
5054
|
+
rawExtraField: rawEntryData.subarray(fileEntry.filenameLength, fileEntry.filenameLength + fileEntry.extraFieldLength),
|
|
4936
5055
|
rawComment,
|
|
4937
5056
|
filename,
|
|
4938
5057
|
comment
|
|
@@ -5440,7 +5559,7 @@
|
|
|
5440
5559
|
if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5441
5560
|
const signatureDataLength = getUint16$1(signatureRecordView, 4);
|
|
5442
5561
|
if (6 + signatureDataLength <= signatureRecordArray.length) {
|
|
5443
|
-
return signatureRecordArray.subarray(6, 6 + signatureDataLength);
|
|
5562
|
+
return new Uint8Array(signatureRecordArray.subarray(6, 6 + signatureDataLength));
|
|
5444
5563
|
}
|
|
5445
5564
|
}
|
|
5446
5565
|
}
|
|
@@ -5963,10 +6082,10 @@
|
|
|
5963
6082
|
if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
|
|
5964
6083
|
pathParts.pop();
|
|
5965
6084
|
}
|
|
5966
|
-
if (
|
|
6085
|
+
if (PARENT_DIRECTORY_REGEXP.test(filename) || filename.startsWith("/") || filename.startsWith("\\") || DRIVE_LETTER_REGEXP.test(filename)) {
|
|
5967
6086
|
return true;
|
|
5968
6087
|
}
|
|
5969
|
-
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
|
|
6088
|
+
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes("") || filename.includes("\0"));
|
|
5970
6089
|
}
|
|
5971
6090
|
|
|
5972
6091
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
@@ -6052,7 +6171,7 @@
|
|
|
6052
6171
|
}
|
|
6053
6172
|
|
|
6054
6173
|
function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
|
|
6055
|
-
return { offset, buffer: scanArray.
|
|
6174
|
+
return { offset, buffer: new Uint8Array(scanArray.subarray(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH)).buffer };
|
|
6056
6175
|
}
|
|
6057
6176
|
|
|
6058
6177
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
@@ -8699,7 +8818,7 @@
|
|
|
8699
8818
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8700
8819
|
*/
|
|
8701
8820
|
|
|
8702
|
-
const VERSION = "2.
|
|
8821
|
+
const VERSION = "2.16.0";
|
|
8703
8822
|
|
|
8704
8823
|
/*
|
|
8705
8824
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|