-
Notifications
You must be signed in to change notification settings - Fork 322
Open
Description
This code:
package main
import "time"
import "github.com/spf13/cast"
func main() {
var now *time.Time
var s string
var err error
s, err= cast.ToStringE(now)
println(s, err)
}Produces a segfault.
I see in the caste.go file, function ToStringE this line, which seems handle this case:
switch s := i.(type) {
...
case nil:
return "", nil
case fmt.Stringer:
return s.String(), nil
...
}Unfortunately, the nil case is not handled, and the nil *time.Time match the fmt.Stringer prototype. The result is a segfault.
To prevent this behaviour I control the input with this code:
var v reflect.Value
v = reflect.ValueOf(val)
switch v.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice:
if v.IsNil() {
return "", nil
}
}
return cast.ToStringE(UntypedValue(val))Does the ToStringE need to support this case and the library needs a fix, or I lust control my inputs ? I think It will be better to the function ToStringE accept any kind of inputs, it will be easier to use the function.
It seems there are only two cases of interface dereference:
case fmt.Stringer:
return s.String(), nil
case error:
return s.Error(), nilSo, a fix could be:
case fmt.Stringer:
if s == nil {
return "", nil
}
return s.String(), nil
case error:
if s == nil {
return "", nil
}
return s.Error(), nilNote: I do not look for other cast function to search similar behavior.
Metadata
Metadata
Assignees
Labels
No labels