segmentio / encoding

Go package containing implementations of efficient encoding, decoding, and validation APIs.
MIT License
987 stars 52 forks source link

Different output when using anonymous fields and omitempty tags #63

Open gouyelliot opened 3 years ago

gouyelliot commented 3 years ago

Hello,

I recently tried using your library in one of our software, and I'd like to report an issue that we have when doing so.

The output when calling Marshal on encoding/json and segmentio/encoding/json differs.

I was able to reproduce the error using the following code:

package main

import (
    "encoding/json"
    "fmt"
    segmentio "github.com/segmentio/encoding/json"
)

type MyStruct struct {
    MyField string `json:"my_field,omitempty"`
}

type MyStruct2 struct {
    *MyStruct
    Code int `json:"code"`
}

func main() {
    value := MyStruct2{
        MyStruct: &MyStruct{
            MyField: "test",
        },
        Code: 0,
    }

    res, _ := json.Marshal(value)
    fmt.Println(string(res)) // Prints {"my_field":"test","code":0}

    res, _ = segmentio.Marshal(value)
    fmt.Println(string(res)) // Prints {"code":0} - Not correct

    value2 := MyStruct2{
        MyStruct: &MyStruct{
            MyField: "test",
        },
        Code:     10,
    }

    res, _ = json.Marshal(value2)
    fmt.Println(string(res)) // Prints {"my_field":"test","code":10}

    res, _ = segmentio.Marshal(value2)
    fmt.Println(string(res)) // Prints {"my_field":"test","code":10}
}

Note that when removing the omitempty tag from MyStruct.MyField, the output is correct.

Segmentio Encoding Version: 0.2.7 Golang Version: 1.15.7 OS: macOS Catalina 10.15.7

dominicbarnes commented 3 years ago

Sorry for the late follow-up here, I've been working on a solution to this as we definitely have bugs internally when it comes to the handling of embedded pointers specifically.

If you need a workaround right now, embedding the same struct without a pointer works as expected. I'll continue working on a proper solution to this problem in the meantime.