From 91c53cd3f7eb4584c8dd53a350229b127b6271c3 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 18 Feb 2021 12:13:49 +0900 Subject: [PATCH] Fix decoding of prefilled value --- decode_array.go | 16 ++++++++++++++-- decode_map.go | 10 ++++++++-- decode_test.go | 2 -- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/decode_array.go b/decode_array.go index 9b6336f..f19e11c 100644 --- a/decode_array.go +++ b/decode_array.go @@ -11,9 +11,11 @@ type arrayDecoder struct { alen int structName string fieldName string + zeroValue unsafe.Pointer } func newArrayDecoder(dec decoder, elemType *rtype, alen int, structName, fieldName string) *arrayDecoder { + zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType)) return &arrayDecoder{ valueDecoder: dec, elemType: elemType, @@ -21,6 +23,7 @@ func newArrayDecoder(dec decoder, elemType *rtype, alen int, structName, fieldNa alen: alen, structName: structName, fieldName: fieldName, + zeroValue: zeroValue, } } @@ -46,13 +49,18 @@ func (d *arrayDecoder) decodeStream(s *stream, p unsafe.Pointer) error { return err } } + idx++ s.skipWhiteSpace() switch s.char() { case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } s.cursor++ return nil case ',': - idx++ + continue case nul: if s.read() { continue @@ -115,13 +123,17 @@ func (d *arrayDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer) (int64 } cursor = c } + idx++ cursor = skipWhiteSpace(buf, cursor) switch buf[cursor] { case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } cursor++ return cursor, nil case ',': - idx++ continue default: return 0, errInvalidCharacter(buf[cursor], "array", cursor) diff --git a/decode_map.go b/decode_map.go index 716d1f1..095b2ba 100644 --- a/decode_map.go +++ b/decode_map.go @@ -47,7 +47,10 @@ func (d *mapDecoder) decodeStream(s *stream, p unsafe.Pointer) error { return errExpected("{ character for map value", s.totalOffset()) } s.skipWhiteSpace() - mapValue := makemap(d.mapType, 0) + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } if s.buf[s.cursor+1] == '}' { *(*unsafe.Pointer)(p) = mapValue s.cursor += 2 @@ -116,7 +119,10 @@ func (d *mapDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer) (int64, } cursor++ cursor = skipWhiteSpace(buf, cursor) - mapValue := makemap(d.mapType, 0) + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } if buf[cursor] == '}' { **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue cursor++ diff --git a/decode_test.go b/decode_test.go index c00d428..4a4a171 100644 --- a/decode_test.go +++ b/decode_test.go @@ -2412,7 +2412,6 @@ func TestSkipArrayObjects(t *testing.T) { } } -/* // Test semantics of pre-filled data, such as struct fields, map elements, // slices, and arrays. // Issues 4900 and 8837, among others. @@ -2466,7 +2465,6 @@ func TestPrefilled(t *testing.T) { } } } -*/ var invalidUnmarshalTests = []struct { v interface{}