diff options
author | Rob Pike <r@golang.org> | 2009-11-16 23:32:30 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2009-11-16 23:32:30 -0800 |
commit | 92ba369b0adaa73e09b9b2764f821d234696df6b (patch) | |
tree | 725ed68c8e8549c4c6e26f6ef1e76aa2a5381879 /src/pkg/gob/decoder.go | |
parent | 7e6b32703d34fa3913817fde6f0a935021fb1ab4 (diff) | |
download | golang-92ba369b0adaa73e09b9b2764f821d234696df6b.tar.gz |
Rework gobs to fix bad bug related to sharing of id's between encoder and decoder side.
Fix is to move all decoder state into the decoder object.
Fixes issue 215.
R=rsc
CC=golang-dev
http://codereview.appspot.com/155077
Diffstat (limited to 'src/pkg/gob/decoder.go')
-rw-r--r-- | src/pkg/gob/decoder.go | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/pkg/gob/decoder.go b/src/pkg/gob/decoder.go index dde5d823f..1713a3e59 100644 --- a/src/pkg/gob/decoder.go +++ b/src/pkg/gob/decoder.go @@ -8,17 +8,20 @@ import ( "bytes"; "io"; "os"; + "reflect"; "sync"; ) // A Decoder manages the receipt of type and data information read from the // remote side of a connection. type Decoder struct { - mutex sync.Mutex; // each item must be received atomically - r io.Reader; // source of the data - seen map[typeId]*wireType; // which types we've already seen described - state *decodeState; // reads data from in-memory buffer - countState *decodeState; // reads counts from wire + mutex sync.Mutex; // each item must be received atomically + r io.Reader; // source of the data + wireType map[typeId]*wireType; // map from remote ID to local description + decoderCache map[reflect.Type]map[typeId]**decEngine; // cache of compiled engines + ignorerCache map[typeId]**decEngine; // ditto for ignored objects + state *decodeState; // reads data from in-memory buffer + countState *decodeState; // reads counts from wire buf []byte; oneByte []byte; } @@ -27,8 +30,10 @@ type Decoder struct { func NewDecoder(r io.Reader) *Decoder { dec := new(Decoder); dec.r = r; - dec.seen = make(map[typeId]*wireType); + dec.wireType = make(map[typeId]*wireType); dec.state = newDecodeState(nil); // buffer set in Decode(); rest is unimportant + dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine); + dec.ignorerCache = make(map[typeId]**decEngine); dec.oneByte = make([]byte, 1); return dec; @@ -36,16 +41,16 @@ func NewDecoder(r io.Reader) *Decoder { func (dec *Decoder) recvType(id typeId) { // Have we already seen this type? That's an error - if _, alreadySeen := dec.seen[id]; alreadySeen { + if _, alreadySeen := dec.wireType[id]; alreadySeen { dec.state.err = os.ErrorString("gob: duplicate type received"); return; } // Type: wire := new(wireType); - decode(dec.state.b, tWireType, wire); + dec.state.err = dec.decode(tWireType, wire); // Remember we've seen this type. - dec.seen[id] = wire; + dec.wireType[id] = wire; } // Decode reads the next value from the connection and stores @@ -97,7 +102,13 @@ func (dec *Decoder) Decode(e interface{}) os.Error { } // No, it's a value. - dec.state.err = decode(dec.state.b, id, e); + // Make sure the type has been defined already. + _, ok := dec.wireType[id]; + if !ok { + dec.state.err = errBadType; + break; + } + dec.state.err = dec.decode(id, e); break; } return dec.state.err; |