From ded60722fa372eb0a26adf4ee59642d4e70c30e0 Mon Sep 17 00:00:00 2001 From: Ville Vesilehto Date: Wed, 28 Jan 2026 14:40:02 +0200 Subject: [PATCH] fix(builtin): bounds check to get() Validate argument count before accessing params slice in the get() function. This prevents a runtime panic when malformed input bypasses compile-time validation, as discovered by OSS-Fuzz. Includes regression test for the specific fuzz case. Signed-off-by: Ville Vesilehto --- builtin/builtin_test.go | 15 +++++++++++++++ builtin/lib.go | 3 +++ 2 files changed, 18 insertions(+) diff --git a/builtin/builtin_test.go b/builtin/builtin_test.go index 9f5e1924..b7ad16fd 100644 --- a/builtin/builtin_test.go +++ b/builtin/builtin_test.go @@ -300,6 +300,21 @@ func TestBuiltin_errors(t *testing.T) { } } +// The get() builtin must return an error when called with +// insufficient arguments at runtime, even if compile-time checks +// are bypassed (regression test for OSS-Fuzz #479270603). +func TestBuiltin_get_runtime_args_check(t *testing.T) { + code := `$env(''matches'i'?t:get().UTC())` + env := map[string]any{"t": 1} + + program, err := expr.Compile(code, expr.Env(env)) + require.NoError(t, err) + + _, err = expr.Run(program, env) + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid number of arguments") +} + func TestBuiltin_types(t *testing.T) { env := map[string]any{ "num": 42, diff --git a/builtin/lib.go b/builtin/lib.go index 40ba19e9..622612cb 100644 --- a/builtin/lib.go +++ b/builtin/lib.go @@ -564,6 +564,9 @@ func flatten(arg reflect.Value, depth int) ([]any, error) { } func get(params ...any) (out any, err error) { + if len(params) < 2 { + return nil, fmt.Errorf("invalid number of arguments (expected 2, got %d)", len(params)) + } from := params[0] i := params[1] v := reflect.ValueOf(from)