diff --git a/src/encoding/json/scanner_test.go b/src/encoding/json/scanner_test.go index fb64463599..a062e91243 100644 --- a/src/encoding/json/scanner_test.go +++ b/src/encoding/json/scanner_test.go @@ -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)) } }) diff --git a/src/encoding/json/v2_indent.go b/src/encoding/json/v2_indent.go index 2655942b12..b2e8518471 100644 --- a/src/encoding/json/v2_indent.go +++ b/src/encoding/json/v2_indent.go @@ -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 } diff --git a/src/encoding/json/v2_scanner_test.go b/src/encoding/json/v2_scanner_test.go index bec5521274..8885520e6d 100644 --- a/src/encoding/json/v2_scanner_test.go +++ b/src/encoding/json/v2_scanner_test.go @@ -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)) } })