mirror of
https://github.com/golang/go.git
synced 2025-10-19 19:13:18 +00:00
encoding/json: fix Indent trailing whitespace regression in goexperiment.jsonv2
The Indent function preserves trailing whitespace, while the v1 emulation under v2 implementation accidentally dropped it. There was prior logic that attempted to preserve it, but it did not work correctly since it ran in a defer and accidentally mutated the dst input argument rather than the output argument. Move the logic to the end and avoid a defer. Also, add a test to both v1 and v1in2 to codify this behavior. This only modifies code that is compiled in under goexperiment.jsonv2. Updates #13520 Fixes #74806 Change-Id: I22b1a8da5185eb969e2a8a111b625d3752cfcbe8 Reviewed-on: https://go-review.googlesource.com/c/go/+/692195 Reviewed-by: Sean Liao <sean@liao.dev> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Sean Liao <sean@liao.dev>
This commit is contained in:
parent
925149da20
commit
691af6ca28
3 changed files with 10 additions and 12 deletions
|
@ -74,6 +74,7 @@ func TestCompactAndIndent(t *testing.T) {
|
|||
-5e+2
|
||||
]`},
|
||||
{Name(""), "{\"\":\"<>&\u2028\u2029\"}", "{\n\t\"\": \"<>&\u2028\u2029\"\n}"}, // See golang.org/issue/34070
|
||||
{Name(""), `null`, "null \n\r\t"}, // See golang.org/issue/13520 and golang.org/issue/74806
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
for _, tt := range tests {
|
||||
|
@ -102,7 +103,7 @@ func TestCompactAndIndent(t *testing.T) {
|
|||
buf.Reset()
|
||||
if err := Indent(&buf, []byte(tt.compact), "", "\t"); err != nil {
|
||||
t.Errorf("%s: Indent error: %v", tt.Where, err)
|
||||
} else if got := buf.String(); got != tt.indent {
|
||||
} else if got := buf.String(); got != strings.TrimRight(tt.indent, " \n\r\t") {
|
||||
t.Errorf("%s: Compact:\n\tgot: %s\n\twant: %s", tt.Where, indentNewlines(got), indentNewlines(tt.indent))
|
||||
}
|
||||
})
|
||||
|
|
|
@ -88,17 +88,8 @@ func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
|||
}
|
||||
|
||||
func appendIndent(dst, src []byte, prefix, indent string) ([]byte, error) {
|
||||
// In v2, trailing whitespace is discarded, while v1 preserved it.
|
||||
dstLen := len(dst)
|
||||
if n := len(src) - len(bytes.TrimRight(src, " \n\r\t")); n > 0 {
|
||||
// Append the trailing whitespace afterwards.
|
||||
defer func() {
|
||||
if len(dst) > dstLen {
|
||||
dst = append(dst, src[len(src)-n:]...)
|
||||
}
|
||||
}()
|
||||
}
|
||||
// In v2, only spaces and tabs are allowed, while v1 allowed any character.
|
||||
dstLen := len(dst)
|
||||
if len(strings.Trim(prefix, " \t"))+len(strings.Trim(indent, " \t")) > 0 {
|
||||
// Use placeholder spaces of correct length, and replace afterwards.
|
||||
invalidPrefix, invalidIndent := prefix, indent
|
||||
|
@ -129,5 +120,10 @@ func appendIndent(dst, src []byte, prefix, indent string) ([]byte, error) {
|
|||
if err != nil {
|
||||
return dst[:dstLen], transformSyntacticError(err)
|
||||
}
|
||||
|
||||
// In v2, trailing whitespace is discarded, while v1 preserved it.
|
||||
if n := len(src) - len(bytes.TrimRight(src, " \n\r\t")); n > 0 {
|
||||
dst = append(dst, src[len(src)-n:]...)
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ func TestCompactAndIndent(t *testing.T) {
|
|||
-5e+2
|
||||
]`},
|
||||
{Name(""), "{\"\":\"<>&\u2028\u2029\"}", "{\n\t\"\": \"<>&\u2028\u2029\"\n}"}, // See golang.org/issue/34070
|
||||
{Name(""), `null`, "null \n\r\t"}, // See golang.org/issue/13520 and golang.org/issue/74806
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
for _, tt := range tests {
|
||||
|
@ -102,7 +103,7 @@ func TestCompactAndIndent(t *testing.T) {
|
|||
buf.Reset()
|
||||
if err := Indent(&buf, []byte(tt.compact), "", "\t"); err != nil {
|
||||
t.Errorf("%s: Indent error: %v", tt.Where, err)
|
||||
} else if got := buf.String(); got != tt.indent {
|
||||
} else if got := buf.String(); got != strings.TrimRight(tt.indent, " \n\r\t") {
|
||||
t.Errorf("%s: Compact:\n\tgot: %s\n\twant: %s", tt.Where, indentNewlines(got), indentNewlines(tt.indent))
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue