@zip.js/zip.js 2.8.42 → 2.8.43

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/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zip-js/zip-js",
3
- "version": "2.8.42",
3
+ "version": "2.8.43",
4
4
  "exports": {
5
5
  ".": "./index.js",
6
6
  "./external": "./lib/zip-fs-external.js",
@@ -1958,6 +1958,7 @@ const FORMAT_GZIP = "gzip";
1958
1958
  const GZIP_HEADER_LENGTH = 10;
1959
1959
  const GZIP_TRAILER_LENGTH = 8;
1960
1960
  const GZIP_HEADER_BYTES = [0x1f, 0x8b, 0x08];
1961
+ const GZIP_OUTPUT_STALL_TIMEOUT = 5000;
1961
1962
 
1962
1963
  class DeflateStream extends TransformStream {
1963
1964
 
@@ -2058,26 +2059,73 @@ class GzipToRawDeflateStream extends TransformStream {
2058
2059
  }
2059
2060
  }
2060
2061
 
2061
- class RawDeflateToGzipStream extends TransformStream {
2062
-
2063
- constructor(signature, uncompressedSize) {
2064
- super({
2065
- start(controller) {
2066
- const header = new Uint8Array(GZIP_HEADER_LENGTH);
2067
- header.set(GZIP_HEADER_BYTES);
2068
- controller.enqueue(header);
2069
- },
2070
- transform(chunk, controller) {
2071
- controller.enqueue(chunk);
2072
- },
2073
- flush(controller) {
2074
- const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2075
- const dataView = getDataView(trailer);
2076
- dataView.setUint32(0, signature, true);
2077
- dataView.setUint32(4, uncompressedSize, true);
2078
- controller.enqueue(trailer);
2062
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
2063
+ const crc32 = new Crc32();
2064
+ let outputLength = 0;
2065
+ let inputDone = false;
2066
+ let watchdogTimeout;
2067
+ let resolveTrailerReady, rejectTrailerReady;
2068
+ const trailerReady = new Promise((resolve, reject) => {
2069
+ resolveTrailerReady = resolve;
2070
+ rejectTrailerReady = reject;
2071
+ });
2072
+ trailerReady.catch(() => { });
2073
+ if (!outputSize) {
2074
+ resolveTrailerReady();
2075
+ }
2076
+ const gzipWrapStream = new TransformStream({
2077
+ start(controller) {
2078
+ const header = new Uint8Array(GZIP_HEADER_LENGTH);
2079
+ header.set(GZIP_HEADER_BYTES);
2080
+ controller.enqueue(header);
2081
+ },
2082
+ transform(chunk, controller) {
2083
+ controller.enqueue(chunk);
2084
+ },
2085
+ async flush(controller) {
2086
+ inputDone = true;
2087
+ startWatchdog();
2088
+ try {
2089
+ await trailerReady;
2090
+ } finally {
2091
+ stopWatchdog();
2079
2092
  }
2080
- });
2093
+ const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2094
+ const dataView = getDataView(trailer);
2095
+ dataView.setUint32(0, crc32.get(), true);
2096
+ dataView.setUint32(4, outputSize, true);
2097
+ controller.enqueue(trailer);
2098
+ },
2099
+ cancel(reason) {
2100
+ rejectTrailerReady(reason);
2101
+ }
2102
+ });
2103
+ const outputStream = new TransformStream({
2104
+ transform(chunk, controller) {
2105
+ crc32.append(chunk);
2106
+ outputLength += chunk.length;
2107
+ if (outputLength >= outputSize) {
2108
+ resolveTrailerReady();
2109
+ } else if (inputDone) {
2110
+ startWatchdog();
2111
+ }
2112
+ controller.enqueue(chunk);
2113
+ },
2114
+ cancel(reason) {
2115
+ rejectTrailerReady(reason);
2116
+ }
2117
+ });
2118
+ readable = pipeThrough(readable, gzipWrapStream);
2119
+ readable = pipeThroughBackpressured(readable, gzipStream);
2120
+ return pipeThrough(readable, outputStream);
2121
+
2122
+ function startWatchdog() {
2123
+ stopWatchdog();
2124
+ watchdogTimeout = setTimeout(() => rejectTrailerReady(new Error(ERR_INVALID_UNCOMPRESSED_SIZE)), GZIP_OUTPUT_STALL_TIMEOUT);
2125
+ }
2126
+
2127
+ function stopWatchdog() {
2128
+ clearTimeout(watchdogTimeout);
2081
2129
  }
2082
2130
  }
2083
2131
 
@@ -2104,7 +2152,7 @@ class InflateStream extends TransformStream {
2104
2152
  try {
2105
2153
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib);
2106
2154
  } catch (error) {
2107
- if (deflate64 || (encrypted && !zipCrypto) || signature === UNDEFINED_VALUE || outputSize === UNDEFINED_VALUE) {
2155
+ if (deflate64 || outputSize === UNDEFINED_VALUE) {
2108
2156
  throw error;
2109
2157
  }
2110
2158
  let gzipStream;
@@ -2113,8 +2161,7 @@ class InflateStream extends TransformStream {
2113
2161
  } catch {
2114
2162
  throw error;
2115
2163
  }
2116
- readable = pipeThrough(readable, new RawDeflateToGzipStream(signature, outputSize));
2117
- readable = pipeThroughBackpressured(readable, gzipStream);
2164
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize);
2118
2165
  }
2119
2166
  }
2120
2167
  readable = mapInflateStreamError(readable);
@@ -2134,25 +2181,38 @@ class InflateStream extends TransformStream {
2134
2181
  }
2135
2182
  }
2136
2183
 
2137
- const deflateRawSupportByStream = new Map();
2184
+ const formatSupportByStream = new Map();
2138
2185
 
2139
- function supportsDeflateRaw(StreamClass) {
2186
+ function supportsFormat(StreamClass, format) {
2140
2187
  if (!StreamClass) {
2141
2188
  return false;
2142
2189
  }
2143
- let supported = deflateRawSupportByStream.get(StreamClass);
2190
+ let supportByFormat = formatSupportByStream.get(StreamClass);
2191
+ if (!supportByFormat) {
2192
+ supportByFormat = new Map();
2193
+ formatSupportByStream.set(StreamClass, supportByFormat);
2194
+ }
2195
+ let supported = supportByFormat.get(format);
2144
2196
  if (supported === UNDEFINED_VALUE) {
2145
2197
  try {
2146
- new StreamClass(FORMAT_DEFLATE_RAW);
2198
+ new StreamClass(format);
2147
2199
  supported = true;
2148
2200
  } catch {
2149
2201
  supported = false;
2150
2202
  }
2151
- deflateRawSupportByStream.set(StreamClass, supported);
2203
+ supportByFormat.set(format, supported);
2152
2204
  }
2153
2205
  return supported;
2154
2206
  }
2155
2207
 
2208
+ function supportsDeflateRaw(StreamClass) {
2209
+ return supportsFormat(StreamClass, FORMAT_DEFLATE_RAW);
2210
+ }
2211
+
2212
+ function supportsGzip(StreamClass) {
2213
+ return supportsFormat(StreamClass, FORMAT_GZIP);
2214
+ }
2215
+
2156
2216
  function setReadable(stream, readable, flush) {
2157
2217
  readable = pipeThrough(readable, new TransformStream({ flush }));
2158
2218
  Object.defineProperty(stream, "readable", {
@@ -2455,6 +2515,25 @@ function configureWorker({ initModule: initModuleFunction }) {
2455
2515
  initModule$1 = initModuleFunction;
2456
2516
  }
2457
2517
 
2518
+ async function supportsDeflate(config) {
2519
+ const { CompressionStream: NativeStream, CompressionStreamZlib: ZlibStream } = config;
2520
+ if (ZlibStream && !ZlibStream.requiresModule) {
2521
+ return true;
2522
+ }
2523
+ if (supportsDeflateRaw(NativeStream) || supportsGzip(NativeStream)) {
2524
+ return true;
2525
+ }
2526
+ if (ZlibStream) {
2527
+ try {
2528
+ await initModule$1(config);
2529
+ return true;
2530
+ } catch {
2531
+ return false;
2532
+ }
2533
+ }
2534
+ return false;
2535
+ }
2536
+
2458
2537
  function resetWebWorkerSupport() {
2459
2538
  webWorkerSupported = UNDEFINED_VALUE;
2460
2539
  }
@@ -5828,6 +5907,11 @@ async function addFile(zipWriter, name, reader, options) {
5828
5907
  zipWriter.files.set(name, UNDEFINED_VALUE);
5829
5908
  let fileEntry;
5830
5909
  try {
5910
+ const { resolvedOptions } = metadataInfo;
5911
+ if (resolvedOptions.level != 0 && resolvedOptions.compressionMethod === UNDEFINED_VALUE &&
5912
+ !resolvedOptions.passThrough && !(await supportsDeflate(zipWriter.config))) {
5913
+ resolvedOptions.level = 0;
5914
+ }
5831
5915
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
5832
5916
  ({ reader } = sizesInfo);
5833
5917
  const diskOffset = getDiskOffset(zipWriter.writer);
@@ -6048,9 +6132,6 @@ function resolveMetadata(zipWriter, name, options) {
6048
6132
  if (level !== UNDEFINED_VALUE && level != 6) {
6049
6133
  useCompressionStream = false;
6050
6134
  }
6051
- if (!useCompressionStream && !registeredCodec && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamZlib === UNDEFINED_VALUE)) {
6052
- level = 0;
6053
- }
6054
6135
  const zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
6055
6136
  if (!zipCrypto && (password !== UNDEFINED_VALUE || rawPassword !== UNDEFINED_VALUE) && !(encryptionStrength >= 1 && encryptionStrength <= 3)) {
6056
6137
  throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);