Commit 1f6e18fd authored by Rob Pike's avatar Rob Pike

handle some error conditions involving bad data.

R=rsc
DELTA=32  (24 added, 1 deleted, 7 changed)
OCL=32461
CL=32463
parent 2946069e
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
var ( var (
errBadUint = os.ErrorString("gob: encoded unsigned integer out of range"); 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"); errRange = os.ErrorString("gob: internal error: field numbers out of bounds");
errNotStruct = os.ErrorString("gob: TODO: can only handle structs") errNotStruct = os.ErrorString("gob: TODO: can only handle structs")
) )
...@@ -768,6 +769,10 @@ func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error { ...@@ -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()) return os.ErrorString("gob: decode can't handle " + rt.String())
} }
typeLock.Lock(); typeLock.Lock();
if _, ok := idToType[wireId]; !ok {
typeLock.Unlock();
return errBadType;
}
enginePtr, err := getDecEnginePtr(wireId, rt); enginePtr, err := getDecEnginePtr(wireId, rt);
typeLock.Unlock(); typeLock.Unlock();
if err != nil { if err != nil {
......
...@@ -64,11 +64,11 @@ func (dec *Decoder) Decode(e interface{}) os.Error { ...@@ -64,11 +64,11 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
dec.state.err = nil; dec.state.err = nil;
for { for {
// Read a count. // Read a count.
nbytes, err := decodeUintReader(dec.r, dec.oneByte); var nbytes uint64;
if err != nil { nbytes, dec.state.err = decodeUintReader(dec.r, dec.oneByte);
return err; if dec.state.err != nil {
break;
} }
// Allocate the buffer. // Allocate the buffer.
if nbytes > uint64(len(dec.buf)) { if nbytes > uint64(len(dec.buf)) {
dec.buf = make([]byte, nbytes + 1000); dec.buf = make([]byte, nbytes + 1000);
...@@ -77,12 +77,13 @@ func (dec *Decoder) Decode(e interface{}) os.Error { ...@@ -77,12 +77,13 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
// Read the data // Read the data
var n int; var n int;
n, err = dec.r.Read(dec.buf[0:nbytes]); n, dec.state.err = io.ReadFull(dec.r, dec.buf[0:nbytes]);
if err != nil { if dec.state.err != nil {
return err; break;
} }
if n < int(nbytes) { if n < int(nbytes) {
return os.ErrorString("gob decode: short read"); dec.state.err = io.ErrUnexpectedEOF;
break;
} }
// Receive a type id. // Receive a type id.
......
...@@ -7,6 +7,7 @@ package gob ...@@ -7,6 +7,7 @@ package gob
import ( import (
"bytes"; "bytes";
"gob"; "gob";
"io";
"os"; "os";
"reflect"; "reflect";
"strings"; "strings";
...@@ -227,3 +228,19 @@ func TestWrongTypeDecoder(t *testing.T) { ...@@ -227,3 +228,19 @@ func TestWrongTypeDecoder(t *testing.T) {
badTypeCheck(new(ET3), false, "different name of field", t); badTypeCheck(new(ET3), false, "different name of field", t);
badTypeCheck(new(ET4), true, "different type 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment