From 5613693f083dab319c8a98b62d7d35acd6880c94 Mon Sep 17 00:00:00 2001 From: blotus Date: Thu, 9 Mar 2023 13:48:26 +0100 Subject: [PATCH] runtime.Fetch: add string type assertion check before trying to check if the value is a method (#349) --- expr_test.go | 26 ++++++++++++++++++++++++++ vm/runtime/runtime.go | 8 +++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/expr_test.go b/expr_test.go index b80010fd5..a62e330e3 100644 --- a/expr_test.go +++ b/expr_test.go @@ -1613,6 +1613,32 @@ func TestIssue271(t *testing.T) { require.Equal(t, 1.0, output) } +type Issue346Array []Issue346Type + +type Issue346Type struct { + Bar string +} + +func (i Issue346Array) Len() int { + return len(i) +} + +func TestIssue346(t *testing.T) { + code := `Foo[0].Bar` + + env := map[string]interface{}{ + "Foo": Issue346Array{ + {Bar: "bar"}, + }, + } + program, err := expr.Compile(code, expr.Env(env)) + require.NoError(t, err) + + output, err := expr.Run(program, env) + require.NoError(t, err) + require.Equal(t, "bar", output) +} + func TestCompile_allow_to_use_interface_to_get_an_element_from_map(t *testing.T) { code := `{"value": "ok"}[vars.key]` env := map[string]interface{}{ diff --git a/vm/runtime/runtime.go b/vm/runtime/runtime.go index 154a319fb..93ead17bf 100644 --- a/vm/runtime/runtime.go +++ b/vm/runtime/runtime.go @@ -18,9 +18,11 @@ func Fetch(from, i interface{}) interface{} { // Methods can be defined on any type. if v.NumMethod() > 0 { - method := v.MethodByName(i.(string)) - if method.IsValid() { - return method.Interface() + if methodName, ok := i.(string); ok { + method := v.MethodByName(methodName) + if method.IsValid() { + return method.Interface() + } } }