Skip to content

Commit 12e4dda

Browse files
committed
fix(vm): validate arg count before OpCall
Prevent index out of bounds panic when calling a function with more arguments than it accepts. The VM now validates argument count before attempting to access parameter types, providing a clear error message instead of a cryptic "index out of range [0] with length 0" panic. This issue was discovered by clusterfuzz with the expression: $env(''matches' '? :now().UTC(g).d)// Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
1 parent 4ff281d commit 12e4dda

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

vm/vm.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,18 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
372372
}
373373
fnType := fn.Type()
374374
size := arg
375-
in := make([]reflect.Value, size)
376375
isVariadic := fnType.IsVariadic()
377376
numIn := fnType.NumIn()
377+
if isVariadic {
378+
if size < numIn-1 {
379+
panic(fmt.Sprintf("invalid number of arguments: expected at least %d, got %d", numIn-1, size))
380+
}
381+
} else {
382+
if size != numIn {
383+
panic(fmt.Sprintf("invalid number of arguments: expected %d, got %d", numIn, size))
384+
}
385+
}
386+
in := make([]reflect.Value, size)
378387
for i := int(size) - 1; i >= 0; i-- {
379388
param := vm.pop()
380389
if param == nil {

vm/vm_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,3 +1491,22 @@ func TestVM_StackUnderflow(t *testing.T) {
14911491
})
14921492
}
14931493
}
1494+
1495+
func TestVM_OpCall_InvalidNumberOfArguments(t *testing.T) {
1496+
// This test ensures that calling a function with wrong number of arguments
1497+
// produces a clear error message instead of a panic.
1498+
// Regression test for clusterfuzz issue with expression:
1499+
// $env(''matches' '? :now().UTC(g).d)//
1500+
1501+
env := map[string]any{
1502+
"ok": true,
1503+
}
1504+
1505+
code := `$env('' matches ' '? : now().UTC(g))`
1506+
program, err := expr.Compile(code, expr.Env(env))
1507+
require.NoError(t, err)
1508+
1509+
_, err = expr.Run(program, env)
1510+
require.Error(t, err)
1511+
require.Contains(t, err.Error(), "invalid number of arguments")
1512+
}

0 commit comments

Comments
 (0)