From 742c4385220e510a108b776d36af3c8570fdbc1d Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Wed, 22 Feb 2023 23:56:44 +0100 Subject: [PATCH] Fix builtins checks for nil args --- builtin/builtin.go | 15 +++++++++++---- checker/checker_test.go | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/builtin/builtin.go b/builtin/builtin.go index 4ea819a7f..ad9376962 100644 --- a/builtin/builtin.go +++ b/builtin/builtin.go @@ -34,7 +34,7 @@ var Builtins = map[int]*Function{ if len(args) != 1 { return anyType, fmt.Errorf("invalid number of arguments for len (expected 1, got %d)", len(args)) } - switch args[0].Kind() { + switch kind(args[0]) { case reflect.Array, reflect.Map, reflect.Slice, reflect.String, reflect.Interface: return integerType, nil } @@ -48,7 +48,7 @@ var Builtins = map[int]*Function{ if len(args) != 1 { return anyType, fmt.Errorf("invalid number of arguments for abs (expected 1, got %d)", len(args)) } - switch args[0].Kind() { + switch kind(args[0]) { case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Interface: return args[0], nil } @@ -62,7 +62,7 @@ var Builtins = map[int]*Function{ if len(args) != 1 { return anyType, fmt.Errorf("invalid number of arguments for int (expected 1, got %d)", len(args)) } - switch args[0].Kind() { + switch kind(args[0]) { case reflect.Interface: return integerType, nil case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: @@ -80,7 +80,7 @@ var Builtins = map[int]*Function{ if len(args) != 1 { return anyType, fmt.Errorf("invalid number of arguments for float (expected 1, got %d)", len(args)) } - switch args[0].Kind() { + switch kind(args[0]) { case reflect.Interface: return floatType, nil case reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: @@ -92,3 +92,10 @@ var Builtins = map[int]*Function{ }, }, } + +func kind(t reflect.Type) reflect.Kind { + if t == nil { + return reflect.Invalid + } + return t.Kind() +} diff --git a/checker/checker_test.go b/checker/checker_test.go index ba612a4c4..eba6a1f81 100644 --- a/checker/checker_test.go +++ b/checker/checker_test.go @@ -875,3 +875,21 @@ func TestCheck_Function_without_types(t *testing.T) { require.NotNil(t, tree.Node.(*ast.CallNode).Func) require.Equal(t, "add", tree.Node.(*ast.CallNode).Func.Name) } + +func TestCheck_dont_panic_on_nil_arguments_for_builtins(t *testing.T) { + tests := []string{ + "len(nil)", + "abs(nil)", + "int(nil)", + "float(nil)", + } + for _, test := range tests { + t.Run(test, func(t *testing.T) { + tree, err := parser.Parse(test) + require.NoError(t, err) + + _, err = checker.Check(tree, conf.New(nil)) + require.Error(t, err) + }) + } +}