jinzhu / copier

Copier for golang, copy value from struct to struct and more
MIT License
5.58k stars 490 forks source link

Copy with nested pointer to struct causes panic #31

Closed sudo-suhas closed 3 years ago

sudo-suhas commented 7 years ago

The following code causes a panic:

package main

import "github.com/jinzhu/copier"

func main() {
    type nested struct {
        A string
    }
    type parentA struct {
        *nested
    }
    type parentB struct {
        *nested
    }
    a := parentA{nested: &nested{A: "a"}}
    b := parentB{}

    copier.Copy(&b, &a)
}

stack trace:

$ go run copier_panic.go
panic: reflect: indirection through nil pointer to embedded struct

goroutine 1 [running]:
reflect.Value.FieldByIndex(0x4d4fe0, 0xc04206e020, 0x199, 0xc0420500d0, 0x2, 0x2, 0x0, 0x568f40, 0x4c8a00)
        C:/tools/go/src/reflect/value.go:804 +0x276
reflect.Value.FieldByName(0x4d4fe0, 0xc04206e020, 0x199, 0x4b5ea6, 0x1, 0x4c8a00, 0xc042044250, 0x198)
        C:/tools/go/src/reflect/value.go:820 +0x16e
github.com/jinzhu/copier.Copy(0x4c2a60, 0xc04206e020, 0x4c2a20, 0xc04206e018, 0x0, 0x0)
        E:/workspace/golang/src/github.com/jinzhu/copier/copier.go:71 +0x491
main.main()
        E:/workspace/golang/src/playground/copier_panic.go:18 +0xb1
exit status 2

The issue originates from this: https://github.com/jinzhu/copier/blob/db4671f3a9b8df855e993f7c94ec5ef1ffb0a23b/copier.go#L71

Is this something that can be fixed in copier? I don't know enough about reflection but if you can guide me, I can make a PR to fix this.

PumpkinSeed commented 6 years ago

Possible it's trying to call the reflectValue.Elem() on a nil reflect.Value, so it won't have an exact Elem(). But correct me if I'm not right.

bazaglia commented 6 years ago

@sudo-suhas have you found any fix for this?

sudo-suhas commented 6 years ago

No.

prism4time commented 5 years ago
b.nested = &nested{}

initialize the pointer can avoid panic.

https://play.golang.org/p/o4m2S_pqJPH

PumpkinSeed commented 5 years ago

@qzyse2017 Can't agree, it's just a temporary solution. What if we have 300 nested field? It should be handled inside the library, if the nested field is nil, then reflect.New with the type of the field.

georgysavva commented 4 years ago

Hey. Any update on this? Is fix coming to the library?

math-nao commented 3 years ago

This example uses unexported anonymous fields. Unexported fields cannot be copied to. PR #72 adds support for exported anonymous fields and avoid panic in case of anonymous fields.