diff options
author | Rob Pike <r@golang.org> | 2009-07-29 15:10:29 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2009-07-29 15:10:29 -0700 |
commit | 517b830fc3b0c2a92a78ac5a247fc55887851f78 (patch) | |
tree | 228eff533d96d815e6a3d6da5663e92f5fb6b62c /src | |
parent | 475f98271e13aa68604ad6dcb90b32067667cb9d (diff) | |
download | golang-517b830fc3b0c2a92a78ac5a247fc55887851f78.tar.gz |
handle some error conditions involving bad data.
R=rsc
DELTA=32 (24 added, 1 deleted, 7 changed)
OCL=32461
CL=32463
Diffstat (limited to 'src')
-rw-r--r-- | src/pkg/gob/decode.go | 5 | ||||
-rw-r--r-- | src/pkg/gob/decoder.go | 17 | ||||
-rw-r--r-- | src/pkg/gob/encoder_test.go | 17 |
3 files changed, 31 insertions, 8 deletions
diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go index 9cd238736..f790a70c2 100644 --- a/src/pkg/gob/decode.go +++ b/src/pkg/gob/decode.go @@ -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 { diff --git a/src/pkg/gob/decoder.go b/src/pkg/gob/decoder.go index 91bfcbbb8..b4c0acdfa 100644 --- a/src/pkg/gob/decoder.go +++ b/src/pkg/gob/decoder.go @@ -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. diff --git a/src/pkg/gob/encoder_test.go b/src/pkg/gob/encoder_test.go index 3e82d8f76..06420c08e 100644 --- a/src/pkg/gob/encoder_test.go +++ b/src/pkg/gob/encoder_test.go @@ -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); +} |