risor-io / risor

Fast and flexible scripting for Go developers and DevOps.
https://risor.io
Apache License 2.0
610 stars 26 forks source link

panic occurs while accessing proxy object field #232

Closed runsisi closed 1 month ago

runsisi commented 5 months ago
type Service struct {
    Name *string
}

func main() {
    code := `
    print(service.Name)
`

    _, err := risor.Eval(context.Background(), code, risor.WithGlobals(map[string]any{
        "service": Service{Name: nil},
    }))
    if err != nil {
        fmt.Println(err)
    }
}

the code above panics:

panic: reflect: call of reflect.Value.Interface on zero Value

maybe we should add IsNil check on FieldByName(name) and return object.Nil if it is true ^1?

myzie commented 5 months ago

thanks @runsisi, that sounds right. do you want to open the PR for this one?

luisdavim commented 5 months ago

There's value.CanInterface couldn't we use that before calling value.Interface since calling IsNil can also panic if called on the wrong type?

runsisi commented 5 months ago

sorry for the wrong hint, the actual panic occurs in type conversion:

var value interface{}
if p.typ.IsPointerType() {
    value = reflect.ValueOf(p.obj).Elem().FieldByName(name).Interface()
} else {
    value = reflect.ValueOf(p.obj).FieldByName(name).Interface()
}
result, err := conv.From(value) // <--- here

https://github.com/risor-io/risor/blob/v1.6.0/object/proxy.go#L86

func (c *PointerConverter) From(obj interface{}) (Object, error) {
    v := reflect.ValueOf(obj).Elem().Interface() // <--- here
    return c.valueConverter.From(v)
}

https://github.com/risor-io/risor/blob/v1.6.0/object/typeconv.go#L972

233 updated, ptal