]> Cypherpunks repositories - gostls13.git/commitdiff
handle some error conditions involving bad data.
authorRob Pike <r@golang.org>
Wed, 29 Jul 2009 22:10:29 +0000 (15:10 -0700)
committerRob Pike <r@golang.org>
Wed, 29 Jul 2009 22:10:29 +0000 (15:10 -0700)
R=rsc
DELTA=32  (24 added, 1 deleted, 7 changed)
OCL=32461
CL=32463

src/pkg/gob/decode.go
src/pkg/gob/decoder.go
src/pkg/gob/encoder_test.go

index 9cd23873693e936bc864798a40e191f7e1012ad8..f790a70c2f972445dde236e7e8b70f6174d56bc0 100644 (file)
@@ -19,6 +19,7 @@ import (
 
 var (
        errBadUint = os.ErrorString("gob: encoded unsigned integer out of range");
+       errBadType = os.ErrorString("gob: unknown type id or corrupted data");
        errRange = os.ErrorString("gob: internal error: field numbers out of bounds");
        errNotStruct = os.ErrorString("gob: TODO: can only handle structs")
 )
@@ -768,6 +769,10 @@ func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error {
                return os.ErrorString("gob: decode can't handle " + rt.String())
        }
        typeLock.Lock();
+       if _, ok := idToType[wireId]; !ok {
+               typeLock.Unlock();
+               return errBadType;
+       }
        enginePtr, err := getDecEnginePtr(wireId, rt);
        typeLock.Unlock();
        if err != nil {
index 91bfcbbb8ef6f516eff5191618632b9cd4c378a5..b4c0acdfa75594d9bf8e9fa7b21eaba64f6082d8 100644 (file)
@@ -64,11 +64,11 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
        dec.state.err = nil;
        for {
                // Read a count.
-               nbytes, err := decodeUintReader(dec.r, dec.oneByte);
-               if err != nil {
-                       return err;
+               var nbytes uint64;
+               nbytes, dec.state.err = decodeUintReader(dec.r, dec.oneByte);
+               if dec.state.err != nil {
+                       break;
                }
-
                // Allocate the buffer.
                if nbytes > uint64(len(dec.buf)) {
                        dec.buf = make([]byte, nbytes + 1000);
@@ -77,12 +77,13 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
 
                // Read the data
                var n int;
-               n, err = dec.r.Read(dec.buf[0:nbytes]);
-               if err != nil {
-                       return err;
+               n, dec.state.err = io.ReadFull(dec.r, dec.buf[0:nbytes]);
+               if dec.state.err != nil {
+                       break;
                }
                if n < int(nbytes) {
-                       return os.ErrorString("gob decode: short read");
+                       dec.state.err = io.ErrUnexpectedEOF;
+                       break;
                }
 
                // Receive a type id.
index 3e82d8f76eaf97b3823c69e817d47a2cff6bd1eb..06420c08e3e556f038b20c3d971b7aadbe52c3cc 100644 (file)
@@ -7,6 +7,7 @@ package gob
 import (
        "bytes";
        "gob";
+       "io";
        "os";
        "reflect";
        "strings";
@@ -227,3 +228,19 @@ func TestWrongTypeDecoder(t *testing.T) {
        badTypeCheck(new(ET3), false, "different name of field", t);
        badTypeCheck(new(ET4), true, "different type of field", t);
 }
+
+func corruptDataCheck(s string, err os.Error, t *testing.T) {
+       b := bytes.NewBuffer(strings.Bytes(s));
+       dec := NewDecoder(b);
+       dec.Decode(new(ET2));
+       if dec.state.err != err {
+               t.Error("expected error", err, "got", dec.state.err);
+       }
+}
+
+// Check that we survive bad data.
+func TestBadData(t *testing.T) {
+       corruptDataCheck("\x01\x01\x01", os.EOF, t);
+       corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t);
+       corruptDataCheck("\x03now is the time for all good men", errBadType, t);
+}