Skip to content

fix(builtin): guard against missing args in builtins#943

Draft
thevilledev wants to merge 1 commit intoexpr-lang:masterfrom
thevilledev:fix/fuzz-5912218922450944
Draft

fix(builtin): guard against missing args in builtins#943
thevilledev wants to merge 1 commit intoexpr-lang:masterfrom
thevilledev:fix/fuzz-5912218922450944

Conversation

@thevilledev
Copy link
Contributor

@thevilledev thevilledev commented Mar 7, 2026

Motivation

Relates to #941.

OSS-Fuzz finding has a fuzzed expression which calls join() with zero arguments inside a method call on an any-typed value (e.g. fn().N(join())). The type checker's callNode() skips argument validation when the callee resolves to an unknown type, so the invalid call passes compilation. At runtime join() accesses args[0] on an empty slice, producing a Go runtime panic instead of a clean error.

I found similar issues from other builtins, relying solely on compile-time validation that can be bypassed.

Changes

Add runtime len(args) guards to a number of builtin functions. Each now returns a descriptive error.

Added the new error format to fuzzing harness allowlist (not enough arguments to call x).

I also removed some autogenerated test lines that called first and last with wrong arity. These tests were passing because of defer recover() silently swallowing the panic.

Further comments

I think there is a chance to fix this in the checker, to provide compile-time rejection. But I guess it'll be quite complicated because of optional chaining on unknown types for a number of different expressions. This fix is the conservative kind just to have clean and descriptive runtime errors.

The type checker skips argument validation for calls where the
callee has unknown type (e.g. method calls on any-typed values).
This allowed builtins like join() to reach runtime with zero
arguments, panicking on args[0] access.

Add runtime len(args) guards to a number of builtin functions that
previously accessed args elements without bounds checking.

Also fix date() to check len(args) a second time after stripping
a leading *time.Location argument.

Relates to OSS-Fuzz finding in expr-lang#941.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant