Skip to content

zlib: validate flush kind for brotli streams#63746

Open
Ic3b3rg wants to merge 1 commit into
nodejs:mainfrom
Ic3b3rg:fix/zlib-brotli-flush-invalid-kind
Open

zlib: validate flush kind for brotli streams#63746
Ic3b3rg wants to merge 1 commit into
nodejs:mainfrom
Ic3b3rg:fix/zlib-brotli-flush-invalid-kind

Conversation

@Ic3b3rg
Copy link
Copy Markdown

@Ic3b3rg Ic3b3rg commented Jun 4, 2026

Summary

BrotliCompress.flush(kind) and BrotliDecompress.flush(kind) forwarded any kind value to the native encoder/decoder without validating it. Passing Z_FINISH (4) or Z_BLOCK (5) caused the process to spin at 100% CPU
indefinitely, because brotli has no matching operation and the loop never makes progress.

This PR validates kind against the brotli operation range [0, 3] before the fake-chunk is queued, and throws ERR_OUT_OF_RANGE on invalid input. The check mirrors the validation already done in the ZlibBase constructor for options.flush and options.finishFlush.

Scope

Validation is intentionally limited to brotli streams. Zlib and zstd flush() calls are unchanged. Internal callers of flush() were audited and the only one (Zlib.prototype.params calling flush(Z_SYNC_FLUSH=2)) is in range for brotli — no regression.

Observable behaviour changes (brotli streams only)

Call Before After
flush(4) (Z_FINISH) hang 100% CPU throws ERR_OUT_OF_RANGE
flush(5) (Z_BLOCK) hang 100% CPU throws ERR_OUT_OF_RANGE
flush(6) (Z_TREES) throws ERR_INVALID_ARG_TYPE (incidental, from write(undefined)) throws ERR_OUT_OF_RANGE
flush(0..3) (valid brotli ops) works works
flush(), flush(cb) works (uses default) works (uses default)

Cross-runtime note

Bun is fixing the same bug on their side (oven-sh/bun#31505) but plans to throw ERR_INVALID_ARG_TYPE to match the current incidental behaviour of flush(6) on Node. This PR chooses ERR_OUT_OF_RANGE for internal consistency with the checkRangesOrGetDefault validation already used elsewhere in lib/zlib.js.

Fixes: #63701

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>
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. zlib Issues and PRs related to the zlib subsystem. labels Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. zlib Issues and PRs related to the zlib subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zlib: BrotliCompress.flush() with Z_FINISH or Z_BLOCK hangs at 100% CPU

2 participants