Skip to content

Comments

fix: reject unexported struct fields at runtime#935

Merged
antonmedv merged 1 commit intoexpr-lang:masterfrom
thevilledev:fix/oss-fuzz-486370271
Feb 23, 2026
Merged

fix: reject unexported struct fields at runtime#935
antonmedv merged 1 commit intoexpr-lang:masterfrom
thevilledev:fix/oss-fuzz-486370271

Conversation

@thevilledev
Copy link
Contributor

@thevilledev thevilledev commented Feb 22, 2026

When the type checker cannot determine a concrete struct type at compile time (e.g. ternary with mixed types), field access falls through to dynamic OpFetch at runtime. The Fetch function in vm/runtime and the get function in builtin/lib used FieldByNameFunc which matched unexported fields, then called Interface() on the resulting reflect.Value, causing:

reflect.Value.Interface: cannot return value obtained from unexported field or method

Add IsExported() guards after FieldByNameFunc in both Fetch() and get() so unexported fields are never accessed via reflection. Error output from tests:

str error: cannot fetch str from main.Env (1:23)
 | (true ? v : "string").str
 | ......................^
integer error: cannot fetch integer from main.Env (1:23)
 | (true ? v : "string").integer
 | ......................^

This pattern is part of the allow list in the fuzzing harness, so the issue should clear out once merged.

Relates to #934.

@thevilledev thevilledev marked this pull request as ready for review February 22, 2026 19:09
When the type checker cannot determine a concrete struct type at
compile time (e.g. ternary with mixed types), field access
falls through to dynamic OpFetch at runtime. The Fetch function
in vm/runtime and the get function in builtin/lib used
FieldByNameFunc which matched unexported fields, then called
Interface() on the resulting reflect.Value, causing a reflect
error.

Add IsExported() guards after FieldByNameFunc in both Fetch()
and get() so unexported fields are never accessed via
reflection.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
@thevilledev thevilledev force-pushed the fix/oss-fuzz-486370271 branch from 29923f6 to 350894b Compare February 22, 2026 19:16
@antonmedv antonmedv merged commit 27acc2d into expr-lang:master Feb 23, 2026
20 checks passed
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.

2 participants