Limit number of function parameters and definitions to prevent SEGV (#3460)
This commit is contained in:
1 parent
b33a7634ba
commit
a2741ee0a8
2 files changed
+41
No files matched your search
@@ -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));
|
||||
|
||||
@@ -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 <<EOF
|
||||
jq: error: too many function parameters or local function definitions (max 4095)
|
||||
jq: 1 compile error
|
||||
EOF
|
||||
$JQ -rn '"def f(\([range(4097) | "a\(.)"] | join(";"))): .; f(\([range(4097)] | join(";")))"' > $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 <<EOF
|
||||
jq: error: too many function parameters or local function definitions (max 4095)
|
||||
jq: 1 compile error
|
||||
EOF
|
||||
$JQ -rn '"\([range(4097) | "def f\(.): \(.)"] | join("; ")); \([range(4097) | "f\(.)"] | join(" + "))"' > $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
|
||||
Reference in new issue
Block a user