}
}
-func addrMarshalerEncoder(e *encodeState, v reflect.Value, _ encOpts) {
+func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
va := v.Addr()
if va.IsNil() {
e.WriteString("null")
b, err := m.MarshalJSON()
if err == nil {
// copy JSON into buffer, checking validity.
- err = compact(&e.Buffer, b, true)
+ err = compact(&e.Buffer, b, opts.escapeHTML)
}
if err != nil {
e.error(&MarshalerError{v.Type(), err})
}
}
+type strMarshaler string
+
+func (s strMarshaler) MarshalJSON() ([]byte, error) {
+ return []byte(s), nil
+}
+
+type strPtrMarshaler string
+
+func (s *strPtrMarshaler) MarshalJSON() ([]byte, error) {
+ return []byte(*s), nil
+}
+
func TestEncoderSetEscapeHTML(t *testing.T) {
var c C
var ct CText
Valid int `json:"<>&#! "`
Invalid int `json:"\\"`
}
+
+ // This case is particularly interesting, as we force the encoder to
+ // take the address of the Ptr field to use its MarshalJSON method. This
+ // is why the '&' is important.
+ marshalerStruct := &struct {
+ NonPtr strMarshaler
+ Ptr strPtrMarshaler
+ }{`"<str>"`, `"<str>"`}
+
for _, tt := range []struct {
name string
v interface{}
`{"\u003c\u003e\u0026#! ":0,"Invalid":0}`,
`{"<>&#! ":0,"Invalid":0}`,
},
+ {
+ `"<str>"`, marshalerStruct,
+ `{"NonPtr":"\u003cstr\u003e","Ptr":"\u003cstr\u003e"}`,
+ `{"NonPtr":"<str>","Ptr":"<str>"}`,
+ },
} {
var buf bytes.Buffer
enc := NewEncoder(&buf)