mirror of https://github.com/golang/go.git
encoding/json: fix appendCompact escaping
CL 469555 changed Compact to use append instead of bytes.Buffer.
appendCompact iterates over input src slice and performs escaping
of certain characters.
To optimize copying it does not copy characters one by one
but keeps track of the start offset of the data to copy when
it reaches next character to escape or the end of the input.
This start offset may become greater than input character offset
so copying of preceding data should check this condition.
CL 469555 removed boundary checks for copying data preceding
escaped characters and this change restores them.
Fixes https://github.com/golang/go/issues/63379
Change-Id: I5b7856239f256c67faf58834705675c0aea08cc2
GitHub-Last-Rev: 661576fb54
GitHub-Pull-Request: golang/go#63400
Reviewed-on: https://go-review.googlesource.com/c/go/+/533275
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
b01cb72eb7
commit
67fb851bd5
|
|
@ -1193,3 +1193,29 @@ func TestMarshalerError(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
type marshaledValue string
|
||||
|
||||
func (v marshaledValue) MarshalJSON() ([]byte, error) {
|
||||
return []byte(v), nil
|
||||
}
|
||||
|
||||
func TestIssue63379(t *testing.T) {
|
||||
for _, v := range []string{
|
||||
"[]<",
|
||||
"[]>",
|
||||
"[]&",
|
||||
"[]\u2028",
|
||||
"[]\u2029",
|
||||
"{}<",
|
||||
"{}>",
|
||||
"{}&",
|
||||
"{}\u2028",
|
||||
"{}\u2029",
|
||||
} {
|
||||
_, err := Marshal(marshaledValue(v))
|
||||
if err == nil {
|
||||
t.Errorf("expected error for %q", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,29 +53,37 @@ func appendCompact(dst, src []byte, escape bool) ([]byte, error) {
|
|||
start := 0
|
||||
for i, c := range src {
|
||||
if escape && (c == '<' || c == '>' || c == '&') {
|
||||
dst = append(dst, src[start:i]...)
|
||||
if start < i {
|
||||
dst = append(dst, src[start:i]...)
|
||||
}
|
||||
dst = append(dst, '\\', 'u', '0', '0', hex[c>>4], hex[c&0xF])
|
||||
start = i + 1
|
||||
}
|
||||
// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
|
||||
if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
|
||||
dst = append(dst, src[start:i]...)
|
||||
if start < i {
|
||||
dst = append(dst, src[start:i]...)
|
||||
}
|
||||
dst = append(dst, '\\', 'u', '2', '0', '2', hex[src[i+2]&0xF])
|
||||
start = i + len("\u2029")
|
||||
start = i + 3
|
||||
}
|
||||
v := scan.step(scan, c)
|
||||
if v >= scanSkipSpace {
|
||||
if v == scanError {
|
||||
break
|
||||
}
|
||||
dst = append(dst, src[start:i]...)
|
||||
if start < i {
|
||||
dst = append(dst, src[start:i]...)
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
if scan.eof() == scanError {
|
||||
return dst[:origLen], scan.err
|
||||
}
|
||||
dst = append(dst, src[start:]...)
|
||||
if start < len(src) {
|
||||
dst = append(dst, src[start:]...)
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue