Skip to content

Commit 3c6ea97

Browse files
committed
Fix check for nil interface
1 parent ab801d4 commit 3c6ea97

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

expr_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -876,12 +876,15 @@ func TestExpr_map_default_values_compile_check(t *testing.T) {
876876
func TestExpr_calls_with_nil(t *testing.T) {
877877
env := map[string]interface{}{
878878
"equals": func(a, b interface{}) interface{} {
879+
assert.Nil(t, a, "a is not nil")
880+
assert.Nil(t, b, "b is not nil")
879881
return a == b
880882
},
883+
"is": is{},
881884
}
882885

883886
p, err := expr.Compile(
884-
"a == nil && equals(b, nil)",
887+
"a == nil && equals(b, nil) && is.Nil(c)",
885888
expr.Env(env),
886889
expr.Operator("==", "equals"),
887890
expr.AllowUndefinedVariables(),
@@ -1020,3 +1023,9 @@ func (m mockMapStringStringEnv) Split(s, sep string) []string {
10201023
}
10211024

10221025
type mockMapStringIntEnv map[string]int
1026+
1027+
type is struct{}
1028+
1029+
func (is) Nil(a interface{}) bool {
1030+
return a == nil
1031+
}

vm/vm.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,13 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
251251
in := make([]reflect.Value, call.Size)
252252
for i := call.Size - 1; i >= 0; i-- {
253253
param := vm.pop()
254-
if param == nil {
255-
// In case of nil interface{} (nil type) use this hack,
254+
if param == nil && reflect.TypeOf(param) == nil {
255+
// In case of nil value and nil type use this hack,
256256
// otherwise reflect.Call will panic on zero value.
257-
param = reflect.ValueOf(&in).Elem()
257+
in[i] = reflect.ValueOf(&param).Elem()
258+
} else {
259+
in[i] = reflect.ValueOf(param)
258260
}
259-
in[i] = reflect.ValueOf(param)
260261
}
261262
out := fetchFn(env, call.Name).Call(in)
262263
vm.push(out[0].Interface())
@@ -275,12 +276,13 @@ func (vm *VM) Run(program *Program, env interface{}) interface{} {
275276
in := make([]reflect.Value, call.Size)
276277
for i := call.Size - 1; i >= 0; i-- {
277278
param := vm.pop()
278-
if param == nil {
279-
// In case of nil interface{} (nil type) use this hack,
279+
if param == nil && reflect.TypeOf(param) == nil {
280+
// In case of nil value and nil type use this hack,
280281
// otherwise reflect.Call will panic on zero value.
281-
param = reflect.ValueOf(&in).Elem()
282+
in[i] = reflect.ValueOf(&param).Elem()
283+
} else {
284+
in[i] = reflect.ValueOf(param)
282285
}
283-
in[i] = reflect.ValueOf(param)
284286
}
285287
out := fetchFn(vm.pop(), call.Name).Call(in)
286288
vm.push(out[0].Interface())

0 commit comments

Comments
 (0)