zlib: validate flush kind for brotli streams#63746
Conversation
BrotliCompress/Decompress.flush(kind) forwarded any value to the native layer, causing a 100% CPU hang for kinds outside the brotli operation range (e.g. Z_FINISH). Validate against [0, 3] and throw ERR_OUT_OF_RANGE on invalid input. Fixes: nodejs#63701 Signed-off-by: Ic3b3rg <s.ceccarini94@gmail.com>
Signed-off-by: Ic3b3rg <s.ceccarini94@gmail.com>
|
WTBU that |
|
@Ic3b3rg Any thoughts on the most recent comment here? |
|
@alii The previous Also, after @addaleax’s earlier suggestion, this PR now validates |
Summary
BrotliCompress.flush(kind)andBrotliDecompress.flush(kind)accepted numerickindvalues that are not valid Brotli operations and forwarded them to the native Brotli encoder/decoder.Passing zlib flush constants such as
Z_FINISH(4) orZ_BLOCK(5) could make the process spin at 100% CPU indefinitely, because Brotli only supports operation values in the range0..3.This PR validates
kindfor Brotli streams before queuing the fake flush chunk. Numeric values outside the Brotli operation range now throwERR_OUT_OF_RANGE, matching the existingoptions.flushandoptions.finishFlushvalidation path.Scope
The validation is intentionally limited to Brotli streams. zlib and zstd stream
flush()behavior is unchanged.Valid Brotli operations continue to work:
BROTLI_OPERATION_PROCESS(0)BROTLI_OPERATION_FLUSH(1)BROTLI_OPERATION_FINISH(2)BROTLI_OPERATION_EMIT_METADATA(3)Observable behavior changes
flush(4)/Z_FINISHERR_OUT_OF_RANGEflush(5)/Z_BLOCKERR_OUT_OF_RANGEflush(6)ERR_OUT_OF_RANGEduring validationflush(0..3)flush()/flush(cb)Error type
ERR_OUT_OF_RANGEis intentional for invalid numeric values:kindhas the correct JavaScript type, but the value is outside the valid Brotli operation range. Non-number values should continue to use the existing type-validation behavior.Cross-runtime note
Bun is fixing the same bug on their side (oven-sh/bun#31505) but plans to throw
ERR_INVALID_ARG_TYPEto match the current incidental behaviour offlush(6)on Node. This PR choosesERR_OUT_OF_RANGEfor internal consistency with thecheckRangesOrGetDefaultvalidation already used elsewhere inlib/zlib.js.Fixes: #63701