Skip to content

Commit 1f9065d

Browse files
panvatargos
authored andcommitted
stream: yield expected Error class on zlib errors
PR-URL: #50712 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent af9cd35 commit 1f9065d

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

lib/internal/webstreams/adapters.js

+41-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeFilter,
5+
ArrayPrototypeMap,
6+
Boolean,
7+
ObjectEntries,
48
PromisePrototypeThen,
59
PromiseResolve,
610
SafePromiseAll,
711
SafePromisePrototypeFinally,
12+
SafeSet,
813
TypedArrayPrototypeGetBuffer,
9-
TypedArrayPrototypeGetByteOffset,
1014
TypedArrayPrototypeGetByteLength,
15+
TypedArrayPrototypeGetByteOffset,
16+
TypeError,
1117
Uint8Array,
1218
} = primordials;
1319

@@ -82,6 +88,38 @@ const { UV_EOF } = internalBinding('uv');
8288

8389
const encoder = new TextEncoder();
8490

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+
85123
/**
86124
* @typedef {import('../../stream').Writable} Writable
87125
* @typedef {import('../../stream').Readable} Readable
@@ -137,10 +175,7 @@ function newWritableStreamFromStreamWritable(streamWritable) {
137175
}
138176

139177
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);
144179

145180
cleanup();
146181
// This is a protection against non-standard, legacy streams
@@ -440,10 +475,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj
440475
streamReadable.pause();
441476

442477
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);
447479

448480
cleanup();
449481
// This is a protection against non-standard, legacy streams

test/wpt/status/compression.json

+1-14
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,8 @@
1414
"decompression-corrupt-input.tentative.any.js": {
1515
"fail": {
1616
"expected": [
17-
"truncating the input for 'deflate' should give an error",
1817
"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"
3219
]
3320
}
3421
},

0 commit comments

Comments
 (0)