From 49319198500729fd65bd6d69071f45f2d7ae2aa7 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 14 Feb 2023 11:02:09 -0700 Subject: compat/json: Compact, Indent: Clear the output if there's an error --- ReleaseNotes.md | 3 +++ compat/json/compat.go | 14 ++++++++++-- compat/json/compat_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 613ea0c..e72a664 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -14,6 +14,9 @@ + compat/json.Valid: No longer considers truncated JSON documents to be valid. + + compat/json.Compact, compat/json.Indent: Don't write to the + destination buffer if there is a syntax error. + # v0.3.6 (2023-02-16) Theme: Architectural improvements diff --git a/compat/json/compat.go b/compat/json/compat.go index 300ab2f..1cdbf0b 100644 --- a/compat/json/compat.go +++ b/compat/json/compat.go @@ -157,18 +157,28 @@ func reencode(dst io.Writer, src []byte, cfg lowmemjson.ReEncoderConfig) error { } func Compact(dst *bytes.Buffer, src []byte) error { - return reencode(dst, src, lowmemjson.ReEncoderConfig{ + start := dst.Len() + err := reencode(dst, src, lowmemjson.ReEncoderConfig{ Compact: true, BackslashEscape: lowmemjson.EscapePreserve, }) + if err != nil { + dst.Truncate(start) + } + return err } func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { - return reencode(dst, src, lowmemjson.ReEncoderConfig{ + start := dst.Len() + err := reencode(dst, src, lowmemjson.ReEncoderConfig{ Indent: indent, Prefix: prefix, BackslashEscape: lowmemjson.EscapePreserve, }) + if err != nil { + dst.Truncate(start) + } + return err } func Valid(data []byte) bool { diff --git a/compat/json/compat_test.go b/compat/json/compat_test.go index 5c8f3ee..d513c27 100644 --- a/compat/json/compat_test.go +++ b/compat/json/compat_test.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "testing" "github.com/stretchr/testify/assert" @@ -32,3 +33,59 @@ func TestCompatValid(t *testing.T) { }) } } + +func TestCompatCompact(t *testing.T) { + t.Parallel() + type testcase struct { + In string + Out string + Err string + } + testcases := map[string]testcase{ + "trunc": {In: `{`, Out: ``, Err: `unexpected end of JSON input`}, + "object": {In: `{}`, Out: `{}`}, + } + for tcName, tc := range testcases { + tc := tc + t.Run(tcName, func(t *testing.T) { + t.Parallel() + t.Logf("in=%q", tc.In) + var out bytes.Buffer + err := Compact(&out, []byte(tc.In)) + assert.Equal(t, tc.Out, out.String()) + if tc.Err == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, tc.Err) + } + }) + } +} + +func TestCompatIndent(t *testing.T) { + t.Parallel() + type testcase struct { + In string + Out string + Err string + } + testcases := map[string]testcase{ + "trunc": {In: `{`, Out: ``, Err: `unexpected end of JSON input`}, + "object": {In: `{}`, Out: `{}`}, + } + for tcName, tc := range testcases { + tc := tc + t.Run(tcName, func(t *testing.T) { + t.Parallel() + t.Logf("in=%q", tc.In) + var out bytes.Buffer + err := Indent(&out, []byte(tc.In), ">", ".") + assert.Equal(t, tc.Out, out.String()) + if tc.Err == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, tc.Err) + } + }) + } +} -- cgit v1.2.3