summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-07-29 15:10:29 -0700
committerRob Pike <r@golang.org>2009-07-29 15:10:29 -0700
commit517b830fc3b0c2a92a78ac5a247fc55887851f78 (patch)
tree228eff533d96d815e6a3d6da5663e92f5fb6b62c /src
parent475f98271e13aa68604ad6dcb90b32067667cb9d (diff)
downloadgolang-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.go5
-rw-r--r--src/pkg/gob/decoder.go17
-rw-r--r--src/pkg/gob/encoder_test.go17
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);
+}