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
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)

View File

@ -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++

View File

@ -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{}