ugorji / go

idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]
MIT License
1.83k stars 294 forks source link

Pointer embedded struct handled incorrecly #369

Closed ncsibra closed 2 years ago

ncsibra commented 2 years ago

Hi,

I tried to update from version v1.1.1 to v1.2.7, but I found a bug. Pointer embedded structs are handled incorrectly, when the embedded struct is nil, after a encode/decode the nil struct gets a default value, instead of staying nil.

To reproduce, use this code:

go.mod:

module ugorji-test

go 1.17

require (
    github.com/davecgh/go-spew v1.1.1
    github.com/ugorji/go v1.1.1
//github.com/ugorji/go/codec v1.2.7
)

main.go

package main

import (
    "bytes"
    "fmt"
    "reflect"

    "github.com/davecgh/go-spew/spew"
    "github.com/ugorji/go/codec"
)

type Test struct {
    *Embedded
}

type Embedded struct {
    Field string
}

func main() {
    handle := &codec.MsgpackHandle{}

    orig := &Test{}
    buf := new(bytes.Buffer)

    enc := codec.NewEncoder(buf, handle)
    err := enc.Encode(orig)
    if err != nil {
        panic(err)
    }

    decoded := &Test{}

    dec := codec.NewDecoder(buf, handle)
    err = dec.Decode(decoded)
    if err != nil {
        panic(err)
    }

    if !reflect.DeepEqual(orig, decoded) {
        fmt.Printf("orig: \n%v\n", spew.Sdump(orig))
        fmt.Printf("decoded: \n%v\n", spew.Sdump(decoded))
    } else {
        fmt.Println("orig and decoded are the same")
    }
}

When using v1.1.1 the result will be the orig and decoded are the same message. With v1.2.7:

orig: 
(*main.Test)(0xc000010030)({
 Embedded: (*main.Embedded)(<nil>)
})

decoded:
(*main.Test)(0xc000010038)({
 Embedded: (*main.Embedded)(0xc000012230)({
  Field: (string) ""
 })
})