mirror of
https://github.com/golang/go
synced 2024-11-25 11:27:56 -07:00
encoding/json: escape output from Marshalers.
Fixes #3127. R=rsc, r CC=golang-dev https://golang.org/cl/5707054
This commit is contained in:
parent
ed238ca4e5
commit
99e45e49b7
@ -260,7 +260,7 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
|
|||||||
b, err := m.MarshalJSON()
|
b, err := m.MarshalJSON()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// copy JSON into buffer, checking validity.
|
// copy JSON into buffer, checking validity.
|
||||||
err = Compact(&e.Buffer, b)
|
err = compact(&e.Buffer, b, true)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.error(&MarshalerError{v.Type(), err})
|
e.error(&MarshalerError{v.Type(), err})
|
||||||
|
@ -167,3 +167,22 @@ func TestRefValMarshal(t *testing.T) {
|
|||||||
t.Errorf("got %q, want %q", got, want)
|
t.Errorf("got %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// C implements Marshaler and returns unescaped JSON.
|
||||||
|
type C int
|
||||||
|
|
||||||
|
func (C) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`"<&>"`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMarshalerEscaping(t *testing.T) {
|
||||||
|
var c C
|
||||||
|
const want = `"\u003c\u0026\u003e"`
|
||||||
|
b, err := Marshal(c)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Marshal: %v", err)
|
||||||
|
}
|
||||||
|
if got := string(b); got != want {
|
||||||
|
t.Errorf("got %q, want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,11 +9,24 @@ import "bytes"
|
|||||||
// Compact appends to dst the JSON-encoded src with
|
// Compact appends to dst the JSON-encoded src with
|
||||||
// insignificant space characters elided.
|
// insignificant space characters elided.
|
||||||
func Compact(dst *bytes.Buffer, src []byte) error {
|
func Compact(dst *bytes.Buffer, src []byte) error {
|
||||||
|
return compact(dst, src, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func compact(dst *bytes.Buffer, src []byte, escape bool) error {
|
||||||
origLen := dst.Len()
|
origLen := dst.Len()
|
||||||
var scan scanner
|
var scan scanner
|
||||||
scan.reset()
|
scan.reset()
|
||||||
start := 0
|
start := 0
|
||||||
for i, c := range src {
|
for i, c := range src {
|
||||||
|
if escape && (c == '<' || c == '>' || c == '&') {
|
||||||
|
if start < i {
|
||||||
|
dst.Write(src[start:i])
|
||||||
|
}
|
||||||
|
dst.WriteString(`\u00`)
|
||||||
|
dst.WriteByte(hex[c>>4])
|
||||||
|
dst.WriteByte(hex[c&0xF])
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
v := scan.step(&scan, int(c))
|
v := scan.step(&scan, int(c))
|
||||||
if v >= scanSkipSpace {
|
if v >= scanSkipSpace {
|
||||||
if v == scanError {
|
if v == scanError {
|
||||||
|
Loading…
Reference in New Issue
Block a user