From: Dmitry Volyntsev Date: Fri, 12 Jun 2026 01:36:22 +0000 (-0700) Subject: QuickJS: fix infinite loop on inflate of a stream needing a dictionary X-Git-Tag: 1.0.0~3 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/NGINX-js-1660x332.png%20%22NGINX%20JavaScript%20Banner%22?a=commitdiff_plain;h=a404538a67ee61f7652c4d450d658e6e156081a4;p=njs.git QuickJS: fix infinite loop on inflate of a stream needing a dictionary The qjs inflate loop treated only rc < 0 as an error. Z_NEED_DICT is positive, so a zlib stream with the FDICT flag and no dictionary made inflate() return Z_NEED_DICT with no progress every iteration, spinning forever and growing the output chain on attacker-controlled input. Handle Z_NEED_DICT explicitly, matching the njs zlib module. --- diff --git a/external/qjs_zlib_module.c b/external/qjs_zlib_module.c index 5abf108a..caeb2761 100644 --- a/external/qjs_zlib_module.c +++ b/external/qjs_zlib_module.c @@ -415,6 +415,11 @@ qjs_zlib_ext_inflate(JSContext *ctx, JSValueConst this_val, int argc, goto fail; } + if (rc == Z_NEED_DICT) { + JS_ThrowTypeError(ctx, "failed to inflate, dictionary is required"); + goto fail; + } + njs_chb_written(&chain, chunk_size - stream.avail_out); } diff --git a/test/zlib.t.mjs b/test/zlib.t.mjs index faef1fb0..612a4198 100644 --- a/test/zlib.t.mjs +++ b/test/zlib.t.mjs @@ -93,6 +93,10 @@ let inflateSync_tsuite = { { value: zlib.deflateRawSync('WAKA', {dictionary: Buffer.from('WAKA')}), exception: 'InternalError: failed to inflate the compressed data: invalid distance too far back' }, + + { value: zlib.deflateSync('WAKA WAKA WAKA', {dictionary: Buffer.from('WAKA')}), + raw: false, + exception: 'TypeError: failed to inflate, dictionary is required' }, ]}; run([