Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/fuzz/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func FuzzExpr(f *testing.F) {
regexp.MustCompile(`reflect.Value.MapIndex: value of type .* is not assignable to type .*`),
regexp.MustCompile(`reflect: Call using .* as type .*`),
regexp.MustCompile(`reflect: Call with too few input arguments`),
regexp.MustCompile(`invalid number of arguments`),
regexp.MustCompile(`reflect: call of reflect.Value.Call on .* Value`),
regexp.MustCompile(`reflect: call of reflect.Value.Index on map Value`),
regexp.MustCompile(`reflect: call of reflect.Value.Len on .* Value`),
Expand Down
11 changes: 10 additions & 1 deletion vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,18 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
}
fnType := fn.Type()
size := arg
in := make([]reflect.Value, size)
isVariadic := fnType.IsVariadic()
numIn := fnType.NumIn()
if isVariadic {
if size < numIn-1 {
panic(fmt.Sprintf("invalid number of arguments: expected at least %d, got %d", numIn-1, size))
}
} else {
if size != numIn {
panic(fmt.Sprintf("invalid number of arguments: expected %d, got %d", numIn, size))
}
}
in := make([]reflect.Value, size)
for i := int(size) - 1; i >= 0; i-- {
param := vm.pop()
if param == nil {
Expand Down
19 changes: 19 additions & 0 deletions vm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1491,3 +1491,22 @@ func TestVM_StackUnderflow(t *testing.T) {
})
}
}

func TestVM_OpCall_InvalidNumberOfArguments(t *testing.T) {
// This test ensures that calling a function with wrong number of arguments
// produces a clear error message instead of a panic.
// Regression test for clusterfuzz issue with expression:
// $env(''matches' '? :now().UTC(g).d)//

env := map[string]any{
"ok": true,
}

code := `$env('' matches ' '? : now().UTC(g))`
program, err := expr.Compile(code, expr.Env(env))
require.NoError(t, err)

_, err = expr.Run(program, env)
require.Error(t, err)
require.Contains(t, err.Error(), "invalid number of arguments")
}
Loading