r3labs / diff

A library for diffing golang structures
Mozilla Public License 2.0
895 stars 84 forks source link

[v2.14.0] panic: reflect.Value.Interface: cannot return value obtained from unexported field or method #67

Closed Vilsol closed 3 years ago

Vilsol commented 3 years ago

When trying to use the github.com/deckarep/golang-set library, running a diff on the sets causes a panic from the reflection package.

Here is a minimum reproducible example:

package main

import (
    "github.com/deckarep/golang-set"
    "github.com/r3labs/diff/v2"
)

func main() {
    a := mapset.NewSet("a", "b", "c")
    b := mapset.NewSet("a", "c")
    _, _ = diff.Diff(a, b)
}

And an example error:

panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

goroutine 1 [running]:
reflect.valueInterface({0x8517c0, 0xc000088350, 0x0}, 0xc0)
    C:/Program Files/Go/src/reflect/value.go:1362 +0xd9
reflect.Value.Interface(...)
    C:/Program Files/Go/src/reflect/value.go:1351
github.com/r3labs/diff/v2.(*Differ).diffMap(0x854a00, {0xc000088340, 0x1, 0x1}, {0x854a00, 0xc0000a63a0, 0x854a00}, {0x854a00, 0xc0000a63c0, 0x1b5})
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff_map.go:27 +0x59f
github.com/r3labs/diff/v2.(*Differ).diff(0xc0000e0000, {0xc000088340, 0x1, 0x1}, {0x854a00, 0xc0000a63a0, 0xc0000ac058}, {0x854a00, 0xc0000a63c0, 0x1b5}, ...)
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff.go:182 +0xb30
github.com/r3labs/diff/v2.(*Differ).diffStruct(0xc0000e0000, {0x99a288, 0x0, 0x0}, {0x857020, 0xc0000a63a0, 0x54}, {0x857020, 0xc0000a63c0, 0x199})
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff_struct.go:62 +0xad3
github.com/r3labs/diff/v2.(*Differ).diff(0xc0000e0000, {0x99a288, 0x0, 0x0}, {0x857020, 0xc0000a63a0, 0x92b2d0}, {0x857020, 0xc0000a63c0, 0x199}, ...)
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff.go:166 +0xf1e
github.com/r3labs/diff/v2.(*Differ).diffPtr(0xc0000e0000, {0x99a288, 0x0, 0x0}, {0x863960, 0xc0000a63a0, 0x2e1cf6a7000}, {0x863960, 0xc0000a63c0, 0x16}, ...)
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff_pointer.go:45 +0x5bc
github.com/r3labs/diff/v2.(*Differ).diff(0xc0000e0000, {0x99a288, 0x0, 0x0}, {0x863960, 0xc0000a63a0, 0xc0000cfe01}, {0x863960, 0xc0000a63c0, 0x16}, ...)
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff.go:184 +0xabd
github.com/r3labs/diff/v2.(*Differ).Diff(0xc0000e0000, {0x863960, 0xc0000a63a0}, {0x863960, 0xc0000a63c0})
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff.go:129 +0x1b3
github.com/r3labs/diff/v2.Diff({0x863960, 0xc0000a63a0}, {0x863960, 0xc0000a63c0}, {0x0, 0x2e1cf630598, 0x60})
    C:/Users/Vilsol/go/pkg/mod/github.com/r3labs/diff/v2@v2.14.0/diff.go:72 +0x75
main.main()
    C:/Users/Vilsol/go/src/awesomeProject/difftest/main.go:11 +0x11b

I am using:

purehyperbole commented 3 years ago

Hey @Vilsol ,

Thanks for raising the issue. I will try work on a fix and get back to you.

purehyperbole commented 3 years ago

Hey @Vilsol ,

This should now be fixed on v2.14.1. Could you please test and see if it behaves as you expect?

You will need to change your implementation to:

package main

import (mapset "github.com/deckarep/golang-set"
    "github.com/r3labs/diff/v2"
)

func main() {
    a := mapset.NewSet("a", "b", "c")
    b := mapset.NewSet("a", "c")
    d, _ := diff.NewDiffer(diff.DisableStructValues())

    cl, _ := d.Diff(b, a)
    // produces: [{"type":"delete","path":["s","b"],"from":{},"to":null}]      
}
Vilsol commented 3 years ago

Hi, thanks for the quick update!

Looks like everything is working as expected!