Skip to content

Commit 39c9df6

Browse files
committed
Fix panic in checker
1 parent 931dbf3 commit 39c9df6

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

checker/checker.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ func (v *visitor) MemberNode(node *ast.MemberNode) (reflect.Type, info) {
475475
func (v *visitor) SliceNode(node *ast.SliceNode) (reflect.Type, info) {
476476
t, _ := v.visit(node.Node)
477477

478-
switch t.Kind() {
478+
switch kind(t) {
479479
case reflect.Interface:
480480
// ok
481481
case reflect.String, reflect.Array, reflect.Slice:
@@ -532,7 +532,7 @@ func (v *visitor) CallNode(node *ast.CallNode) (reflect.Type, info) {
532532
fn.NumOut() == 1 &&
533533
fn.Out(0).Kind() == reflect.Interface {
534534
rest := fn.In(fn.NumIn() - 1) // function has only one param for functions and two for methods
535-
if rest.Kind() == reflect.Slice && rest.Elem().Kind() == reflect.Interface {
535+
if kind(rest) == reflect.Slice && rest.Elem().Kind() == reflect.Interface {
536536
node.Fast = true
537537
}
538538
}
@@ -666,7 +666,7 @@ func (v *visitor) checkBuiltinGet(node *ast.BuiltinNode) (reflect.Type, info) {
666666

667667
t, _ := v.visit(val)
668668

669-
switch t.Kind() {
669+
switch kind(t) {
670670
case reflect.Interface:
671671
return anyType, info{}
672672
case reflect.Slice, reflect.Array:
@@ -791,7 +791,7 @@ func (v *visitor) checkArguments(name string, fn reflect.Type, method bool, argu
791791
continue
792792
}
793793

794-
if !t.AssignableTo(in) && t.Kind() != reflect.Interface {
794+
if !t.AssignableTo(in) && kind(t) != reflect.Interface {
795795
return anyType, &file.Error{
796796
Location: arg.Location(),
797797
Message: fmt.Sprintf("cannot use %v as argument (type %v) to call %v ", t, in, name),

checker/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ func deref(t reflect.Type) reflect.Type {
223223
return t
224224
}
225225

226+
func kind(t reflect.Type) reflect.Kind {
227+
if t == nil {
228+
return reflect.Invalid
229+
}
230+
return t.Kind()
231+
}
232+
226233
func isIntegerOrArithmeticOperation(node ast.Node) bool {
227234
switch n := node.(type) {
228235
case *ast.IntegerNode:

compiler/compiler_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/antonmedv/expr"
8+
"github.com/antonmedv/expr/test/playground"
89
"github.com/antonmedv/expr/vm"
910
"github.com/antonmedv/expr/vm/runtime"
1011
"github.com/stretchr/testify/assert"
@@ -278,3 +279,15 @@ func TestCompile(t *testing.T) {
278279
assert.Equal(t, test.program.Disassemble(), program.Disassemble(), test.input)
279280
}
280281
}
282+
283+
func TestCompile_panic(t *testing.T) {
284+
tests := []string{
285+
`(TotalPosts.Profile[Authors > TotalPosts == get(nil, TotalLikes)] > Authors) ^ (TotalLikes / (Posts?.PublishDate[TotalPosts] < Posts))`,
286+
}
287+
for _, test := range tests {
288+
t.Run(test, func(t *testing.T) {
289+
_, err := expr.Compile(test, expr.Env(playground.Blog{}))
290+
require.Error(t, err)
291+
})
292+
}
293+
}

0 commit comments

Comments
 (0)