GeezerVison is showing github.com — stream: yield expected Error class on zlib errors · nodejs/node@2e0abed
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/webstreams/adapters.js +41-9Lines changed: 41 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | 3 | const { | | 4 | + ArrayPrototypeFilter, | | 5 | + ArrayPrototypeMap, | | 6 | + Boolean, | | 7 | + ObjectEntries, | 4 | 8 | PromisePrototypeThen, | 5 | 9 | PromiseResolve, | 6 | 10 | SafePromiseAll, | 7 | 11 | SafePromisePrototypeFinally, | | 12 | + SafeSet, | 8 | 13 | TypedArrayPrototypeGetBuffer, | 9 | | - TypedArrayPrototypeGetByteOffset, | 10 | 14 | TypedArrayPrototypeGetByteLength, | | 15 | + TypedArrayPrototypeGetByteOffset, | | 16 | + TypeError, | 11 | 17 | Uint8Array, | 12 | 18 | } = primordials; | 13 | 19 |
| @@ -82,6 +88,38 @@ const { UV_EOF } = internalBinding('uv'); | 82 | 88 |
| 83 | 89 | const encoder = new TextEncoder(); | 84 | 90 |
| | 91 | +// Collect all negative (error) ZLIB codes and Z_NEED_DICT | | 92 | +const ZLIB_FAILURES = new SafeSet([ | | 93 | + ...ArrayPrototypeFilter( | | 94 | + ArrayPrototypeMap( | | 95 | + ObjectEntries(internalBinding('constants').zlib), | | 96 | + ({ 0: code, 1: value }) => (value < 0 ? code : null), | | 97 | + ), | | 98 | + Boolean, | | 99 | + ), | | 100 | + 'Z_NEED_DICT', | | 101 | +]); | | 102 | + | | 103 | +/** | | 104 | + * @param {Error|null} cause | | 105 | + * @returns {Error|null} | | 106 | + */ | | 107 | +function handleKnownInternalErrors(cause) { | | 108 | + switch (true) { | | 109 | + case cause?.code === 'ERR_STREAM_PREMATURE_CLOSE': { | | 110 | + return new AbortError(undefined, { cause }); | | 111 | + } | | 112 | + case ZLIB_FAILURES.has(cause?.code): { | | 113 | + // eslint-disable-next-line no-restricted-syntax | | 114 | + const error = new TypeError(undefined, { cause }); | | 115 | + error.code = cause.code; | | 116 | + return error; | | 117 | + } | | 118 | + default: | | 119 | + return cause; | | 120 | + } | | 121 | +} | | 122 | + | 85 | 123 | /** | 86 | 124 | * @typedef {import('../../stream').Writable} Writable | 87 | 125 | * @typedef {import('../../stream').Readable} Readable | @@ -137,10 +175,7 @@ function newWritableStreamFromStreamWritable(streamWritable) { | 137 | 175 | } | 138 | 176 |
| 139 | 177 | const cleanup = finished(streamWritable, (error) => { | 140 | | - if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') { | 141 | | - const err = new AbortError(undefined, { cause: error }); | 142 | | - error = err; | 143 | | - } | | 178 | + error = handleKnownInternalErrors(error); | 144 | 179 |
| 145 | 180 | cleanup(); | 146 | 181 | // This is a protection against non-standard, legacy streams | @@ -440,10 +475,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj | 440 | 475 | streamReadable.pause(); | 441 | 476 |
| 442 | 477 | const cleanup = finished(streamReadable, (error) => { | 443 | | - if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') { | 444 | | - const err = new AbortError(undefined, { cause: error }); | 445 | | - error = err; | 446 | | - } | | 478 | + error = handleKnownInternalErrors(error); | 447 | 479 |
| 448 | 480 | cleanup(); | 449 | 481 | // This is a protection against non-standard, legacy streams | |
Collapse file Copy file name to clipboardExpand all lines: test/wpt/status/compression.json +1-14Lines changed: 1 addition & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 14 | 14 | "decompression-corrupt-input.tentative.any.js": { | 15 | 15 | "fail": { | 16 | 16 | "expected": [ | 17 | | - "truncating the input for 'deflate' should give an error", | 18 | 17 | "trailing junk for 'deflate' should give an error", | 19 | | - "format 'deflate' field CMF should be error for 0", | 20 | | - "format 'deflate' field FLG should be error for 157", | 21 | | - "format 'deflate' field DATA should be error for 5", | 22 | | - "format 'deflate' field ADLER should be error for 255", | 23 | | - "truncating the input for 'gzip' should give an error", | 24 | | - "trailing junk for 'gzip' should give an error", | 25 | | - "format 'gzip' field ID should be error for 255", | 26 | | - "format 'gzip' field CM should be error for 0", | 27 | | - "format 'gzip' field FLG should be error for 2", | 28 | | - "format 'gzip' field DATA should be error for 3", | 29 | | - "format 'gzip' field CRC should be error for 0", | 30 | | - "format 'gzip' field ISIZE should be error for 1", | 31 | | - "the deflate input compressed with dictionary should give an error" | | 18 | + "trailing junk for 'gzip' should give an error" | 32 | 19 | ] | 33 | 20 | } | 34 | 21 | }, | |
|