]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1] encoding/gob: fix check for short input in slice decode
authorAndrew Gerrand <adg@golang.org>
Fri, 21 Sep 2012 19:54:04 +0000 (05:54 +1000)
committerAndrew Gerrand <adg@golang.org>
Fri, 21 Sep 2012 19:54:04 +0000 (05:54 +1000)
src/pkg/encoding/gob/decode.go
src/pkg/encoding/gob/encoder_test.go

index e32a178aba396fe2d0cc89d1f746abbb886bf01a..8690b35d71481082e0ef8d8b6aebe641e9a759cc 100644 (file)
@@ -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) {
        instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl}
        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)
                if elemIndir > 1 {
                        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.
 func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
        nr := state.decodeUint()
-       if nr > uint64(state.b.Len()) {
-               errorf("length of slice exceeds input size (%d elements)", nr)
-       }
        n := int(nr)
        if indir > 0 {
                up := unsafe.Pointer(p)
index c4947cbb8d312da0bc98cfc39144d1725d59967a..db824d99917ddf319b6494f6645273df7c1519f3 100644 (file)
@@ -736,3 +736,32 @@ func TestPtrToMapOfMap(t *testing.T) {
                t.Fatalf("expected %v got %v", data, newData)
        }
 }
+
+// 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
+       }
+}