diff options
author | Rob Pike <r@golang.org> | 2009-10-11 17:37:22 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2009-10-11 17:37:22 -0700 |
commit | 92b93dd042130a68d3784c690b74b6db75d7c770 (patch) | |
tree | dc94d68df7ac8250b1af92afb8b1330771a78b89 /src/pkg/gob/decode.go | |
parent | 81355af7a117fb5e2ea9293fc571a5e5ec1f46fe (diff) | |
download | golang-92b93dd042130a68d3784c690b74b6db75d7c770.tar.gz |
fix bugs in gob.
1) didn't handle attempts to encode non-structs properly.
2) if there were multiple indirections involving allocation, didn't allocate the
intermediate cells.
tests added.
R=rsc
DELTA=82 (65 added, 5 deleted, 12 changed)
OCL=35582
CL=35582
Diffstat (limited to 'src/pkg/gob/decode.go')
-rw-r--r-- | src/pkg/gob/decode.go | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/pkg/gob/decode.go b/src/pkg/gob/decode.go index dddc1ec05..415b4b677 100644 --- a/src/pkg/gob/decode.go +++ b/src/pkg/gob/decode.go @@ -355,13 +355,18 @@ type decEngine struct { } func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer, p uintptr, indir int) os.Error { - if indir > 0 { + for ; indir > 0; indir-- { up := unsafe.Pointer(p); if *(*unsafe.Pointer)(up) == nil { - // Allocate the structure by making a slice of bytes and recording the + // Allocate object by making a slice of bytes and recording the // address of the beginning of the array. TODO(rsc). - b := make([]byte, rtyp.Size()); - *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]); + if indir > 1 { // allocate a pointer + b := make([]byte, unsafe.Sizeof((*int)(nil))); + *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]); + } else { // allocate a struct + b := make([]byte, rtyp.Size()); + *(*unsafe.Pointer)(up) = unsafe.Pointer(&b[0]); + } } p = *(*uintptr)(up); } @@ -753,15 +758,10 @@ func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error) { } func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error { - // Dereference down to the underlying object. + // Dereference down to the underlying struct type. rt, indir := indirect(reflect.Typeof(e)); - v := reflect.NewValue(e); - for i := 0; i < indir; i++ { - v = reflect.Indirect(v); - } - var st *reflect.StructValue; - var ok bool; - if st, ok = v.(*reflect.StructValue); !ok { + st, ok := rt.(*reflect.StructType); + if !ok { return os.ErrorString("gob: decode can't handle " + rt.String()); } typeLock.Lock(); @@ -779,7 +779,7 @@ func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error { name := rt.Name(); return os.ErrorString("gob: type mismatch: no fields matched compiling decoder for " + name); } - return decodeStruct(engine, rt.(*reflect.StructType), b, uintptr(v.Addr()), 0); + return decodeStruct(engine, st, b, uintptr(reflect.NewValue(e).Addr()), indir); } func init() { |