From 1037421a838aaab7ced4bc4a440c33cec7feb820 Mon Sep 17 00:00:00 2001 From: IncSW Date: Tue, 15 Jun 2021 18:19:39 +0300 Subject: [PATCH 1/3] fix error when unmarshal empty array --- encode_test.go | 16 ++++++++++++++++ internal/decoder/array.go | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/encode_test.go b/encode_test.go index 41a14cc..c970188 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1958,3 +1958,19 @@ func TestEncodeContextOption(t *testing.T) { } }) } + +func TestIssue251(t *testing.T) { + array := [3]int{1, 2, 3} + err := stdjson.Unmarshal([]byte("[ ]"), &array) + if err != nil { + t.Fatal(err) + } + t.Log(array) + + array = [3]int{1, 2, 3} + err = json.Unmarshal([]byte("[ ]"), &array) + if err != nil { + t.Fatal(err) + } + t.Log(array) +} diff --git a/internal/decoder/array.go b/internal/decoder/array.go index 7f9f1eb..7caaf75 100644 --- a/internal/decoder/array.go +++ b/internal/decoder/array.go @@ -111,8 +111,17 @@ func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe return cursor, nil case '[': idx := 0 - for { + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } cursor++ + return cursor, nil + } + for { if idx < d.alen { c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)) if err != nil { @@ -137,6 +146,7 @@ func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe cursor++ return cursor, nil case ',': + cursor++ continue default: return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor) From 9a2f108208af8c1ba3d1cbe957c65d8cca2231d2 Mon Sep 17 00:00:00 2001 From: IncSW Date: Tue, 15 Jun 2021 19:05:12 +0300 Subject: [PATCH 2/3] fix array stream decoder --- internal/decoder/array.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/decoder/array.go b/internal/decoder/array.go index 7caaf75..21f1fd5 100644 --- a/internal/decoder/array.go +++ b/internal/decoder/array.go @@ -46,8 +46,16 @@ func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) er return nil case '[': idx := 0 - for { + s.cursor++ + if s.skipWhiteSpace() == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } s.cursor++ + return nil + } + for { if idx < d.alen { if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil { return err @@ -67,9 +75,11 @@ func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) er s.cursor++ return nil case ',': + s.cursor++ continue case nul: if s.read() { + s.cursor++ continue } goto ERROR From 94cecc06094f8b5fb3f487563fd7b8131573655e Mon Sep 17 00:00:00 2001 From: IncSW Date: Tue, 15 Jun 2021 19:10:56 +0300 Subject: [PATCH 3/3] update tests --- decode_test.go | 23 +++++++++++++++++++++++ encode_test.go | 16 ---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/decode_test.go b/decode_test.go index f578de2..fb00c36 100644 --- a/decode_test.go +++ b/decode_test.go @@ -3666,3 +3666,26 @@ func TestDecodeContextOption(t *testing.T) { } }) } + +func TestIssue251(t *testing.T) { + array := [3]int{1, 2, 3} + err := stdjson.Unmarshal([]byte("[ ]"), &array) + if err != nil { + t.Fatal(err) + } + t.Log(array) + + array = [3]int{1, 2, 3} + err = json.Unmarshal([]byte("[ ]"), &array) + if err != nil { + t.Fatal(err) + } + t.Log(array) + + array = [3]int{1, 2, 3} + err = json.NewDecoder(strings.NewReader(`[ ]`)).Decode(&array) + if err != nil { + t.Fatal(err) + } + t.Log(array) +} diff --git a/encode_test.go b/encode_test.go index c970188..41a14cc 100644 --- a/encode_test.go +++ b/encode_test.go @@ -1958,19 +1958,3 @@ func TestEncodeContextOption(t *testing.T) { } }) } - -func TestIssue251(t *testing.T) { - array := [3]int{1, 2, 3} - err := stdjson.Unmarshal([]byte("[ ]"), &array) - if err != nil { - t.Fatal(err) - } - t.Log(array) - - array = [3]int{1, 2, 3} - err = json.Unmarshal([]byte("[ ]"), &array) - if err != nil { - t.Fatal(err) - } - t.Log(array) -}