@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-fs-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
|
}
|
|
@@ -3687,10 +3803,11 @@
|
|
|
3687
3803
|
|
|
3688
3804
|
createReadable(options) {
|
|
3689
3805
|
const reader = this;
|
|
3690
|
-
const { useRangeHeader, forceRangeRequests, size } = reader;
|
|
3806
|
+
const { useRangeHeader, forceRangeRequests, size, eocdCache } = reader;
|
|
3691
3807
|
if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
|
|
3692
3808
|
const { offset = 0, size: readSize = size - offset } = options || {};
|
|
3693
|
-
|
|
3809
|
+
const cached = eocdCache && offset >= size - eocdCache.length;
|
|
3810
|
+
if (readSize > 0 && offset < size && !cached) {
|
|
3694
3811
|
return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
|
|
3695
3812
|
}
|
|
3696
3813
|
}
|
|
@@ -4644,6 +4761,7 @@
|
|
|
4644
4761
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4645
4762
|
const MAX_KNOWN_VERSION = 63;
|
|
4646
4763
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4764
|
+
const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
|
|
4647
4765
|
const CHARSET_UTF8 = "utf-8";
|
|
4648
4766
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
4649
4767
|
const CHARSET_CP437 = "cp437";
|
|
@@ -4896,12 +5014,13 @@
|
|
|
4896
5014
|
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
4897
5015
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
4898
5016
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
4899
|
-
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
4900
5017
|
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
4901
5018
|
const endOffset = commentOffset + commentLength;
|
|
4902
|
-
const
|
|
4903
|
-
const
|
|
4904
|
-
const
|
|
5019
|
+
const rawEntryData = new Uint8Array(directoryArray.subarray(filenameOffset, endOffset));
|
|
5020
|
+
const rawFilename = rawEntryData.subarray(0, fileEntry.filenameLength);
|
|
5021
|
+
const rawComment = rawEntryData.subarray(fileEntry.filenameLength + fileEntry.extraFieldLength);
|
|
5022
|
+
const filenameUTF8 = languageEncodingFlag || (!filenameEncoding && isUTF8Text(rawFilename));
|
|
5023
|
+
const commentUTF8 = languageEncodingFlag || (!commentEncoding && isUTF8Text(rawComment));
|
|
4905
5024
|
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
4906
5025
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
4907
5026
|
const msdosAttributes = {
|
|
@@ -4952,7 +5071,7 @@
|
|
|
4952
5071
|
rawFilename,
|
|
4953
5072
|
filenameUTF8,
|
|
4954
5073
|
commentUTF8,
|
|
4955
|
-
rawExtraField:
|
|
5074
|
+
rawExtraField: rawEntryData.subarray(fileEntry.filenameLength, fileEntry.filenameLength + fileEntry.extraFieldLength),
|
|
4956
5075
|
rawComment,
|
|
4957
5076
|
filename,
|
|
4958
5077
|
comment
|
|
@@ -5460,7 +5579,7 @@
|
|
|
5460
5579
|
if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5461
5580
|
const signatureDataLength = getUint16$1(signatureRecordView, 4);
|
|
5462
5581
|
if (6 + signatureDataLength <= signatureRecordArray.length) {
|
|
5463
|
-
return signatureRecordArray.subarray(6, 6 + signatureDataLength);
|
|
5582
|
+
return new Uint8Array(signatureRecordArray.subarray(6, 6 + signatureDataLength));
|
|
5464
5583
|
}
|
|
5465
5584
|
}
|
|
5466
5585
|
}
|
|
@@ -5983,10 +6102,10 @@
|
|
|
5983
6102
|
if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
|
|
5984
6103
|
pathParts.pop();
|
|
5985
6104
|
}
|
|
5986
|
-
if (
|
|
6105
|
+
if (PARENT_DIRECTORY_REGEXP.test(filename) || filename.startsWith("/") || filename.startsWith("\\") || DRIVE_LETTER_REGEXP.test(filename)) {
|
|
5987
6106
|
return true;
|
|
5988
6107
|
}
|
|
5989
|
-
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
|
|
6108
|
+
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes("") || filename.includes("\0"));
|
|
5990
6109
|
}
|
|
5991
6110
|
|
|
5992
6111
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
@@ -6072,7 +6191,7 @@
|
|
|
6072
6191
|
}
|
|
6073
6192
|
|
|
6074
6193
|
function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
|
|
6075
|
-
return { offset, buffer: scanArray.
|
|
6194
|
+
return { offset, buffer: new Uint8Array(scanArray.subarray(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH)).buffer };
|
|
6076
6195
|
}
|
|
6077
6196
|
|
|
6078
6197
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
@@ -8817,7 +8936,7 @@
|
|
|
8817
8936
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8818
8937
|
*/
|
|
8819
8938
|
|
|
8820
|
-
const VERSION = "2.
|
|
8939
|
+
const VERSION = "2.16.0";
|
|
8821
8940
|
|
|
8822
8941
|
/*
|
|
8823
8942
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|