diff --git a/conf/env.go b/conf/env.go index 0acd4457..ab9b56f6 100644 --- a/conf/env.go +++ b/conf/env.go @@ -30,24 +30,25 @@ func EnvWithCache(c *Cache, env any) Nature { } v := reflect.ValueOf(env) + d := deref.Value(v) t := v.Type() - switch deref.Value(v).Kind() { + switch d.Kind() { case reflect.Struct: n := c.FromType(t) n.Strict = true return n case reflect.Map: - n := c.FromType(v.Type()) + n := c.FromType(d.Type()) if n.TypeData == nil { n.TypeData = new(TypeData) } n.Strict = true - n.Fields = make(map[string]Nature, v.Len()) + n.Fields = make(map[string]Nature, d.Len()) - for _, key := range v.MapKeys() { - elem := v.MapIndex(key) + for _, key := range d.MapKeys() { + elem := d.MapIndex(key) if !elem.IsValid() || !elem.CanInterface() { panic(fmt.Sprintf("invalid map value: %s", key)) } diff --git a/test/issues/825/issue_test.go b/test/issues/825/issue_test.go new file mode 100644 index 00000000..5e1d4b38 --- /dev/null +++ b/test/issues/825/issue_test.go @@ -0,0 +1,20 @@ +package main + +import ( + "testing" + + "github.com/expr-lang/expr" + "github.com/expr-lang/expr/internal/testify/require" +) + +func TestIssue825(t *testing.T) { + m := map[string]any{"foo": 42} + env := &m + + prog, err := expr.Compile("foo > 0", expr.Env(env)) + require.NoError(t, err) + + out, err := expr.Run(prog, env) + require.NoError(t, err) + require.Equal(t, true, out) +} diff --git a/vm/vm.go b/vm/vm.go index 8e95d4ea..916406eb 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -47,6 +47,10 @@ type VM struct { } func (vm *VM) Run(program *Program, env any) (_ any, err error) { + if m, ok := env.(*map[string]any); ok && m != nil { + env = *m + } + defer func() { if r := recover(); r != nil { var location file.Location