From c5a58f935908dd9122a228d1eef59b2b4ac4b14a Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 25 Feb 2025 21:13:19 +0800 Subject: [PATCH] fix: bug when marshal nil interface{} that contains not-indirect value (#756) --- .github/workflows/license-check.yml | 14 ---------- internal/encoder/compiler.go | 10 +++---- issue_test/common_test.go | 9 ++++++- issue_test/issue755_test.go | 41 +++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 20 deletions(-) delete mode 100644 .github/workflows/license-check.yml create mode 100644 issue_test/issue755_test.go diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml deleted file mode 100644 index 847cc3efa..000000000 --- a/.github/workflows/license-check.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: License Check - -on: pull_request - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Check License Header - uses: apache/skywalking-eyes/header@v0.4.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go index 902fbc98b..3975d90f4 100644 --- a/internal/encoder/compiler.go +++ b/internal/encoder/compiler.go @@ -626,16 +626,16 @@ func (self *Compiler) compileStructFieldQuoted(p *ir.Program, sp int, vt reflect } func (self *Compiler) compileInterface(p *ir.Program, vt reflect.Type) { - x := p.PC() - p.Add(ir.OP_is_nil_p1) - /* iface and efaces are different */ if vt.NumMethod() == 0 { p.Add(ir.OP_eface) - } else { - p.Add(ir.OP_iface) + return } + x := p.PC() + p.Add(ir.OP_is_nil_p1) + p.Add(ir.OP_iface) + /* the "null" value */ e := p.PC() p.Add(ir.OP_goto) diff --git a/issue_test/common_test.go b/issue_test/common_test.go index 490c04222..282478763 100644 --- a/issue_test/common_test.go +++ b/issue_test/common_test.go @@ -28,4 +28,11 @@ func assertUnmarshal(t *testing.T, api sonic.API, input []byte, newfn func() int jerr := json.Unmarshal(input, jv) assert.Equal(t, jv, sv) assert.Equal(t, serr == nil, jerr == nil) -} \ No newline at end of file +} + +func assertMarshal(t *testing.T, api sonic.API, v interface{}) { + sout, serr := api.Marshal(&v) + jout, jerr := json.Marshal(&v) + assert.Equal(t, jerr == nil, serr == nil, jerr) + assert.Equal(t, jout, sout, v) +} diff --git a/issue_test/issue755_test.go b/issue_test/issue755_test.go new file mode 100644 index 000000000..e2364c80e --- /dev/null +++ b/issue_test/issue755_test.go @@ -0,0 +1,41 @@ +package issue_test + +import ( + "testing" + "github.com/bytedance/sonic" +) + +func TestIssue755_NilEfaceWithDirectValue(t *testing.T) { + tests := []interface{} { + struct { + Foo *int + }{}, + struct { + Foo func() + }{}, + chan int(nil), + } + for _, v := range(tests) { + assertMarshal(t, sonic.ConfigDefault, v) + } +} + +type NilMarshaler struct {} + +func (n *NilMarshaler) MarshalJSON() ([]byte, error) { + if n == nil { + return []byte(`"my null value"`), nil + } + return []byte(`{}`), nil +} + +func TestIssue755_MarshalIface(t *testing.T) { + tests := []interface{} { + &NilMarshaler{}, + (*NilMarshaler)(nil), + } + for _, v := range(tests) { + assertMarshal(t, sonic.ConfigDefault, v) + } +} +