Skip to content

Commit

Permalink
fix: bug when marshal nil interface{} that contains not-indirect value (
Browse files Browse the repository at this point in the history
  • Loading branch information
liuq19 authored Feb 25, 2025
1 parent e30ac4f commit c5a58f9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 20 deletions.
14 changes: 0 additions & 14 deletions .github/workflows/license-check.yml

This file was deleted.

10 changes: 5 additions & 5 deletions internal/encoder/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 8 additions & 1 deletion issue_test/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

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)
}
41 changes: 41 additions & 0 deletions issue_test/issue755_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit c5a58f9

Please sign in to comment.