mirror of
https://github.com/golang/go
synced 2024-10-03 21:21:22 -06:00
encoding/gob: fix check for short input in slice decode
R=golang-dev, dsymonds, r, nigeltao CC=golang-dev https://golang.org/cl/6374059
This commit is contained in:
parent
ac12131649
commit
1fa32d21a9
@ -562,6 +562,9 @@ func (dec *Decoder) ignoreSingle(engine *decEngine) {
|
|||||||
func (dec *Decoder) decodeArrayHelper(state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, length, elemIndir int, ovfl error) {
|
func (dec *Decoder) decodeArrayHelper(state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, length, elemIndir int, ovfl error) {
|
||||||
instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl}
|
instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl}
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
|
if state.b.Len() == 0 {
|
||||||
|
errorf("decoding array or slice: length exceeds input size (%d elements)", length)
|
||||||
|
}
|
||||||
up := unsafe.Pointer(p)
|
up := unsafe.Pointer(p)
|
||||||
if elemIndir > 1 {
|
if elemIndir > 1 {
|
||||||
up = decIndirect(up, elemIndir)
|
up = decIndirect(up, elemIndir)
|
||||||
@ -652,9 +655,6 @@ func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
|
|||||||
// Slices are encoded as an unsigned length followed by the elements.
|
// Slices are encoded as an unsigned length followed by the elements.
|
||||||
func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
|
func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
|
||||||
nr := state.decodeUint()
|
nr := state.decodeUint()
|
||||||
if nr > uint64(state.b.Len()) {
|
|
||||||
errorf("length of slice exceeds input size (%d elements)", nr)
|
|
||||||
}
|
|
||||||
n := int(nr)
|
n := int(nr)
|
||||||
if indir > 0 {
|
if indir > 0 {
|
||||||
up := unsafe.Pointer(p)
|
up := unsafe.Pointer(p)
|
||||||
|
@ -813,3 +813,32 @@ func TestMutipleEncodingsOfBadType(t *testing.T) {
|
|||||||
t.Errorf("expected error about no exported fields; got %v", err)
|
t.Errorf("expected error about no exported fields; got %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There was an error check comparing the length of the input with the
|
||||||
|
// length of the slice being decoded. It was wrong because the next
|
||||||
|
// thing in the input might be a type definition, which would lead to
|
||||||
|
// an incorrect length check. This test reproduces the corner case.
|
||||||
|
|
||||||
|
type Z struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test29ElementSlice(t *testing.T) {
|
||||||
|
Register(Z{})
|
||||||
|
src := make([]interface{}, 100) // Size needs to be bigger than size of type definition.
|
||||||
|
for i := range src {
|
||||||
|
src[i] = Z{}
|
||||||
|
}
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
err := NewEncoder(buf).Encode(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("encode: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dst []interface{}
|
||||||
|
err = NewDecoder(buf).Decode(&dst)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("decode: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user