ugorji / go

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

Shadowed fields in embedded types are not being encoded #159

Closed johnniedoe closed 8 years ago

johnniedoe commented 8 years ago

When encoding structs w/embedded structs, shadowed fields aren't getting encoded. Unfortunately, this occurs even when the fields' encoded names are changed via struct tags.

import (
        "bytes"
        "encoding/json"
        "fmt"

        "github.com/ugorji/go/codec"
)

type Composite struct {
        X string
        Embedded
}

type Embedded struct {
        X string `json:"x"`
}

func main() {
        d := Composite{X:"a",Embedded:Embedded{X:"b"}}
        msg, _ := json.Marshal(d)
        fmt.Println(" json: ", string(msg))

        buf := &bytes.Buffer{}
        codec.NewEncoder(buf, &codec.JsonHandle{}).Encode(d)
        fmt.Println("codec: ", buf.String())
}

In this case, the stdlib encoder encodes both values but the codec encoder only encodes the non-embedded value of the Composite struct.

 json:  {"X":"a","x":"b"}
codec:  {"X":"a"}

Not sure if this is a bug, or just a difference between encoders.

ugorji commented 8 years ago

Difference between encoders.

At the edges, these sort of differences are not surprising.

johnniedoe commented 8 years ago

Fair enough.

While I was looking into this, I did find another interesting case. With the same program, if you instead have the structs

type Composite struct {
    X string
    Embedded
}

type Embedded struct {
    Y string `json:"X"`
}

The stdlib version will not encode the embedded value, while codec will produce an encoded value with two "X" fields.

 json:  {"X":"a"}
codec:  {"X":"a","X":"b"}

In this case, it's unclear what the receiver of such a payload might do with it. Granted, it's also a problem that can usually be avoided w/more judicious use of struct tags.

ugorji commented 8 years ago

This is a bug! On Jun 10, 2016 7:23 AM, "johnniedoe" notifications@github.com wrote:

Fair enough.

While I was looking into this, I did find another interesting case. With the same program, if you instead have the structs

type Composite struct { X string Embedded }

type Embedded struct { Y string json:"X" }

The stdlib version will not encode the embedded value, while codec will produce an encoded value with two "X" fields.

json: {"X":"a"} codec: {"X":"a","X":"b"}

In this case, it's unclear what the receiver of such a payload might do with it. Granted, it's also a problem that can usually be avoided w/more judicious use of struct tags.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ugorji/go/issues/159#issuecomment-225157837, or mute the thread https://github.com/notifications/unsubscribe/ABKlwi80wOyBEWM95IaUp4-PHaWAixnvks5qKUkygaJpZM4IyhSG .