Fix decoding of prefilled value

This commit is contained in:
Masaaki Goshima 2021-02-18 12:13:49 +09:00
parent b2a7d22fb4
commit 91c53cd3f7
3 changed files with 22 additions and 6 deletions

View File

@ -11,9 +11,11 @@ type arrayDecoder struct {
alen int alen int
structName string structName string
fieldName string fieldName string
zeroValue unsafe.Pointer
} }
func newArrayDecoder(dec decoder, elemType *rtype, alen int, structName, fieldName string) *arrayDecoder { func newArrayDecoder(dec decoder, elemType *rtype, alen int, structName, fieldName string) *arrayDecoder {
zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType))
return &arrayDecoder{ return &arrayDecoder{
valueDecoder: dec, valueDecoder: dec,
elemType: elemType, elemType: elemType,
@ -21,6 +23,7 @@ func newArrayDecoder(dec decoder, elemType *rtype, alen int, structName, fieldNa
alen: alen, alen: alen,
structName: structName, structName: structName,
fieldName: fieldName, fieldName: fieldName,
zeroValue: zeroValue,
} }
} }
@ -46,13 +49,18 @@ func (d *arrayDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
return err return err
} }
} }
idx++
s.skipWhiteSpace() s.skipWhiteSpace()
switch s.char() { switch s.char() {
case ']': case ']':
for idx < d.alen {
*(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
idx++
}
s.cursor++ s.cursor++
return nil return nil
case ',': case ',':
idx++ continue
case nul: case nul:
if s.read() { if s.read() {
continue continue
@ -115,13 +123,17 @@ func (d *arrayDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer) (int64
} }
cursor = c cursor = c
} }
idx++
cursor = skipWhiteSpace(buf, cursor) cursor = skipWhiteSpace(buf, cursor)
switch buf[cursor] { switch buf[cursor] {
case ']': case ']':
for idx < d.alen {
*(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
idx++
}
cursor++ cursor++
return cursor, nil return cursor, nil
case ',': case ',':
idx++
continue continue
default: default:
return 0, errInvalidCharacter(buf[cursor], "array", cursor) return 0, errInvalidCharacter(buf[cursor], "array", cursor)

View File

@ -47,7 +47,10 @@ func (d *mapDecoder) decodeStream(s *stream, p unsafe.Pointer) error {
return errExpected("{ character for map value", s.totalOffset()) return errExpected("{ character for map value", s.totalOffset())
} }
s.skipWhiteSpace() 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] == '}' { if s.buf[s.cursor+1] == '}' {
*(*unsafe.Pointer)(p) = mapValue *(*unsafe.Pointer)(p) = mapValue
s.cursor += 2 s.cursor += 2
@ -116,7 +119,10 @@ func (d *mapDecoder) decode(buf []byte, cursor int64, p unsafe.Pointer) (int64,
} }
cursor++ cursor++
cursor = skipWhiteSpace(buf, 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] == '}' { if buf[cursor] == '}' {
**(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
cursor++ cursor++

View File

@ -2412,7 +2412,6 @@ func TestSkipArrayObjects(t *testing.T) {
} }
} }
/*
// Test semantics of pre-filled data, such as struct fields, map elements, // Test semantics of pre-filled data, such as struct fields, map elements,
// slices, and arrays. // slices, and arrays.
// Issues 4900 and 8837, among others. // Issues 4900 and 8837, among others.
@ -2466,7 +2465,6 @@ func TestPrefilled(t *testing.T) {
} }
} }
} }
*/
var invalidUnmarshalTests = []struct { var invalidUnmarshalTests = []struct {
v interface{} v interface{}