diff --git a/api_tests/marshal_json_escape_test.go b/api_tests/marshal_json_escape_test.go new file mode 100644 index 0000000..b50e72f --- /dev/null +++ b/api_tests/marshal_json_escape_test.go @@ -0,0 +1,47 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + jsoniter "github.com/json-iterator/go" + "github.com/stretchr/testify/require" +) + +var marshalConfig = jsoniter.Config{ + EscapeHTML: false, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +type Container struct { + Bar interface{} +} + +func (c *Container) MarshalJSON() ([]byte, error) { + return marshalConfig.Marshal(&c.Bar) +} + +func TestEncodeEscape(t *testing.T) { + should := require.New(t) + + container := &Container{ + Bar: []string{"123", "ooo"}, + } + out, err := marshalConfig.Marshal(container) + should.Nil(err) + bufout := string(out) + + var stdbuf bytes.Buffer + stdenc := json.NewEncoder(&stdbuf) + stdenc.SetEscapeHTML(false) + err = stdenc.Encode(container) + should.Nil(err) + stdout := string(stdbuf.Bytes()) + if stdout[len(stdout)-1:] == "\n" { + stdout = stdout[:len(stdout)-1] + } + + should.Equal(stdout, bufout) +} diff --git a/reflect_marshaler.go b/reflect_marshaler.go index fea5071..3e21f37 100644 --- a/reflect_marshaler.go +++ b/reflect_marshaler.go @@ -3,8 +3,9 @@ package jsoniter import ( "encoding" "encoding/json" - "github.com/modern-go/reflect2" "unsafe" + + "github.com/modern-go/reflect2" ) var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() @@ -93,10 +94,17 @@ func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { stream.WriteNil() return } - bytes, err := json.Marshal(obj) + marshaler := obj.(json.Marshaler) + bytes, err := marshaler.MarshalJSON() if err != nil { stream.Error = err } else { + // html escape was already done by jsoniter + // but the extra '\n' should be trimed + l := len(bytes) + if l > 0 && bytes[l-1] == '\n' { + bytes = bytes[:l-1] + } stream.Write(bytes) } }