Fix some panics related to nil values
This commit is contained in:
parent
4154ce5ce7
commit
a042aaa430
25
salix.go
25
salix.go
@ -404,7 +404,14 @@ func (t *Template) getIndex(i ast.Index, local map[string]any) (any, error) {
|
|||||||
|
|
||||||
var out reflect.Value
|
var out reflect.Value
|
||||||
rval := reflect.ValueOf(val)
|
rval := reflect.ValueOf(val)
|
||||||
|
if !rval.IsValid() {
|
||||||
|
return nil, ast.PosError(i, "%s: cannot get index of nil value", valueToString(i))
|
||||||
|
}
|
||||||
rindex := reflect.ValueOf(index)
|
rindex := reflect.ValueOf(index)
|
||||||
|
if !rval.IsValid() {
|
||||||
|
return nil, ast.PosError(i, "%s: cannot use nil value as an index", valueToString(i))
|
||||||
|
}
|
||||||
|
|
||||||
switch rval.Kind() {
|
switch rval.Kind() {
|
||||||
case reflect.Slice, reflect.Array, reflect.String:
|
case reflect.Slice, reflect.Array, reflect.String:
|
||||||
intType := reflect.TypeOf(0)
|
intType := reflect.TypeOf(0)
|
||||||
@ -448,9 +455,15 @@ func (t *Template) getField(fa ast.FieldAccess, local map[string]any) (any, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rval := reflect.ValueOf(val)
|
rval := reflect.ValueOf(val)
|
||||||
|
if !rval.IsValid() {
|
||||||
|
return nil, ast.PosError(fa, "%s: cannot get field of nil value", valueToString(fa))
|
||||||
|
}
|
||||||
for rval.Kind() == reflect.Pointer {
|
for rval.Kind() == reflect.Pointer {
|
||||||
rval = rval.Elem()
|
rval = rval.Elem()
|
||||||
}
|
}
|
||||||
|
if rval.Kind() != reflect.Struct || rval.NumField() == 0 {
|
||||||
|
return nil, ast.PosError(fa, "%s: value has no fields", valueToString(fa))
|
||||||
|
}
|
||||||
field := rval.FieldByName(fa.Name.Value)
|
field := rval.FieldByName(fa.Name.Value)
|
||||||
if !field.IsValid() {
|
if !field.IsValid() {
|
||||||
return nil, ast.PosError(fa, "%s: no such field: %s", valueToString(fa), fa.Name.Value)
|
return nil, ast.PosError(fa, "%s: no such field: %s", valueToString(fa), fa.Name.Value)
|
||||||
@ -468,6 +481,9 @@ func (t *Template) execMethodCall(mc ast.MethodCall, local map[string]any) (any,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rval := reflect.ValueOf(val)
|
rval := reflect.ValueOf(val)
|
||||||
|
if !rval.IsValid() {
|
||||||
|
return nil, ast.PosError(mc, "%s: cannot call method on nil value", valueToString(mc))
|
||||||
|
}
|
||||||
for rval.Kind() == reflect.Pointer {
|
for rval.Kind() == reflect.Pointer {
|
||||||
rval = rval.Elem()
|
rval = rval.Elem()
|
||||||
}
|
}
|
||||||
@ -487,6 +503,10 @@ func (t *Template) execMethodCall(mc ast.MethodCall, local map[string]any) (any,
|
|||||||
|
|
||||||
// execFunc executes a function call
|
// execFunc executes a function call
|
||||||
func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, local map[string]any) (any, error) {
|
func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, local map[string]any) (any, error) {
|
||||||
|
if !fn.IsValid() {
|
||||||
|
return nil, ast.PosError(node, "%s: cannot call nil function", valueToString(node))
|
||||||
|
}
|
||||||
|
|
||||||
fnType := fn.Type()
|
fnType := fn.Type()
|
||||||
lastIndex := fnType.NumIn() - 1
|
lastIndex := fnType.NumIn() - 1
|
||||||
isVariadic := fnType.IsVariadic()
|
isVariadic := fnType.IsVariadic()
|
||||||
@ -525,12 +545,15 @@ func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, lo
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret := fn.Call(params)
|
ret := fn.Call(params)
|
||||||
|
for ret[0].Kind() == reflect.Pointer {
|
||||||
|
ret[0] = ret[0].Elem()
|
||||||
|
}
|
||||||
if len(ret) == 1 {
|
if len(ret) == 1 {
|
||||||
retv := ret[0].Interface()
|
retv := ret[0].Interface()
|
||||||
if err, ok := retv.(error); ok {
|
if err, ok := retv.(error); ok {
|
||||||
return nil, ast.PosError(node, "%s: %w", valueToString(node), err)
|
return nil, ast.PosError(node, "%s: %w", valueToString(node), err)
|
||||||
}
|
}
|
||||||
return ret[0].Interface(), nil
|
return retv, nil
|
||||||
} else {
|
} else {
|
||||||
if ret[1].IsNil() {
|
if ret[1].IsNil() {
|
||||||
return ret[0].Interface(), nil
|
return ret[0].Interface(), nil
|
||||||
|
Loading…
Reference in New Issue
Block a user