From a2741ee0a8022fd3e47ddc6b8b87db359673cea8 Mon Sep 17 00:00:00 2001 From: Ze Sheng <108382772+OwenSanzas@users.noreply.github.com> Date: Tue, 24 Feb 2026 16:49:40 -0600 Subject: [PATCH] Limit number of function parameters and definitions to prevent SEGV (#3460) --- src/compile.c | 14 ++++++++++++++ tests/shtest | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/compile.c b/src/compile.c index f0be1a5f..5e64946b 100644 --- a/src/compile.c +++ b/src/compile.c @@ -1241,6 +1241,13 @@ static int compile(struct bytecode* bc, block b, struct locfile* lf, jv args, jv if (curr->op == CLOSURE_CREATE) { assert(curr->bound_by == curr); + // Prevent subfunction index from overflowing into ARG_NEWCLOSURE flag + if (bc->nsubfunctions >= ARG_NEWCLOSURE) { + locfile_locate(lf, curr->source, + "too many function parameters or local function definitions (max %d)", ARG_NEWCLOSURE - 1); + errors++; + break; + } curr->imm.intval = bc->nsubfunctions++; } if (curr->op == CLOSURE_CREATE_C) { @@ -1274,6 +1281,13 @@ static int compile(struct bytecode* bc, block b, struct locfile* lf, jv args, jv for (inst* param = curr->arglist.first; param; param = param->next) { assert(param->op == CLOSURE_PARAM); assert(param->bound_by == param); + // Prevent closure index from overflowing into ARG_NEWCLOSURE flag + if (subfn->nclosures >= ARG_NEWCLOSURE) { + locfile_locate(lf, curr->source, + "function has too many parameters (max %d)", ARG_NEWCLOSURE - 1); + errors++; + break; + } param->imm.intval = subfn->nclosures++; param->compiled = subfn; params = jv_array_append(params, jv_string(param->symbol)); diff --git a/tests/shtest b/tests/shtest index e241d4a5..90a96eaf 100755 --- a/tests/shtest +++ b/tests/shtest @@ -844,4 +844,31 @@ if ! $msys && ! $mingw; then fi fi +# Test ARG_NEWCLOSURE overflow protection (issue #3458) +# Test 1: Too many function parameters (4097 params triggers the limit) +echo "Testing function parameter limit..." +cat > $d/expected < $d/prog.jq +$JQ -nf $d/prog.jq 2> $d/out && { + echo "Expected compile error for too many parameters" + exit 1 +} +diff $d/out $d/expected + +# Test 2: Too many local functions (4097 functions triggers the limit) +echo "Testing local function limit..." +cat > $d/expected < $d/prog.jq +$JQ -nf $d/prog.jq 2> $d/out && { + echo "Expected compile error for too many local functions" + exit 1 +} +diff $d/out $d/expected + exit 0