Fix assertion failure on too many parameters in a nested function (#3663)

A call passing more than 4095 arguments at the start of a nested
function body aborted jq after reporting the compile errors, with
"Assertion failed: (nemb > 0 && sz > 0), function jv_mem_calloc" and
exit status 134.

Stop compiling a function before its bytecode is allocated when it has
compile errors, since the bytecode is only generated and used when
compilation succeeds. jq now prints the same compile errors followed by
"jq: 2 compile errors" and exits with status 3, as it does for other
compile errors, instead of crashing.
This commit is contained in:
itchyny
2026-10-10 21:29:56 +09:00
committed by GitHub
parent 04042494cf
commit a5323a369c
2 changed files with 21 additions and 1 deletions
+7 -1
View File
@@ -1306,12 +1306,18 @@ static int compile(struct bytecode* bc, block b, struct locfile* lf, jv args, jv
bc->nsubfunctions = 0;
bc->subfunctions = 0;
}
if (errors) {
bc->code = 0;
bc->constants = jv_invalid();
block_free(b);
return errors;
}
uint16_t* code = jv_mem_calloc(bc->codelen, sizeof(uint16_t));
bc->code = code;
pos = 0;
jv constant_pool = jv_array();
int maxvar = -1;
if (!errors) for (inst* curr = b.first; curr; curr = curr->next) {
for (inst* curr = b.first; curr; curr = curr->next) {
const struct opcode_description* op = opcode_describe(curr->op);
if (op->length == 0)
continue;
+14
View File
@@ -952,6 +952,20 @@ $JQ -nf $d/prog.jq 2> $d/out && {
}
diff $d/out $d/expected
# Test 3: Too many function parameters in a nested function (issue #3661)
echo "Testing function parameter limit in a nested function..."
cat > $d/expected <<EOF
jq: error: function has too many parameters (max 4095)
jq: error: too many function parameters or local function definitions (max 4095)
jq: 2 compile errors
EOF
$JQ -rn '"def g(\([range(4097) | "a\(.)"] | join(";"))): .; def f: g(\([range(4097)] | join(";"))); f"' > $d/prog.jq
$JQ -nf $d/prog.jq 2> $d/out && {
echo "Expected compile error for too many parameters in a nested function"
exit 1
}
diff $d/out $d/expected
# CVE-2026-33948: No NUL truncation in the JSON parser
if printf '{}\x00{}' | $JQ >/dev/null 2> /dev/null; then
printf 'Error expected but jq exited successfully\n' 1>&2