bytedance / sonic

A blazingly fast JSON serializing & deserializing library
Apache License 2.0
6.71k stars 333 forks source link

bug: `omitempy` regard non-empty-type interface as empty #539

Closed AsterDY closed 10 months ago

AsterDY commented 10 months ago

Reproducible codes

type OmitEmptyInterface struct {
    ErrCode int32       `json:"code"`
    Data    interface{} `json:"data,omitempty"`
}

func TestOmitEmptyInterface(t *testing.T) {
    // non-enmpty type
    var data *string
    resp := &OmitEmptyInterface{
       ErrCode: 123,
       Data:    data,
    }
    eout, eerr := json.Marshal(resp)
    sout, serr := sonic.Marshal(resp)
    require.Equal(t, eerr == nil, serr == nil)
    require.Equal(t, string(eout), string(sout))

    // empty type and value
    resp = &OmitEmptyInterface{
        ErrCode: 123,
        Data:    nil,
     }
     eout, eerr = json.Marshal(resp)
     sout, serr = sonic.Marshal(resp)
     require.Equal(t, eerr == nil, serr == nil)
     require.Equal(t, string(eout), string(sout))
}

output

--- FAIL: TestOmitEmptyInterface (0.00s)
    /Users/admin/GOPATH/work/sonic/issue_test/issuexx_test.go:40: 
            Error Trace:    /Users/admin/GOPATH/work/sonic/issue_test/issuexx_test.go:40
            Error:          Not equal: 
                            expected: "{\"code\":123,\"data\":null}"
                            actual  : "{\"code\":123}"

                            Diff:
                            --- Expected
                            +++ Actual
                            @@ -1 +1 @@
                            -{"code":123,"data":null}
                            +{"code":123}
            Test:           TestOmitEmptyInterface

Explaination

sonic check if a interface is empty using second field emptyInterface.word, while std lib using first field emptyInterface.typ

AsterDY commented 10 months ago

540