Browse Source

codec: fix nested naked decoding, especially for lists and extensions

During naked decode, we use a list as a poor man's slab allocator.
When we need to use an item from the slice, we must keep a reference to it outside of the slice.
When nested decode happens, and an append causes a new slice to be created,
we will still be working with the same value.

Fixes #122
Ugorji Nwoke 10 years ago
parent
commit
28147d9923
1 changed files with 5 additions and 4 deletions
  1. 5 4
      codec/decode.go

+ 5 - 4
codec/decode.go

@@ -601,8 +601,9 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
 		if d.stid == 0 || d.stid == intfSliceTypId {
 		if d.stid == 0 || d.stid == intfSliceTypId {
 			l := len(n.ss)
 			l := len(n.ss)
 			n.ss = append(n.ss, nil)
 			n.ss = append(n.ss, nil)
-			d.decode(&n.ss[l])
-			rvn = reflect.ValueOf(&n.ss[l]).Elem()
+			var v2 interface{} = &n.ss[l]
+			d.decode(v2)
+			rvn = reflect.ValueOf(v2).Elem()
 			n.ss = n.ss[:l]
 			n.ss = n.ss[:l]
 		} else {
 		} else {
 			rvn = reflect.New(d.h.SliceType).Elem()
 			rvn = reflect.New(d.h.SliceType).Elem()
@@ -615,8 +616,8 @@ func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) {
 			l := len(n.is)
 			l := len(n.is)
 			n.is = append(n.is, nil)
 			n.is = append(n.is, nil)
 			v2 := &n.is[l]
 			v2 := &n.is[l]
-			n.is = n.is[:l]
 			d.decode(v2)
 			d.decode(v2)
+			n.is = n.is[:l]
 			v = *v2
 			v = *v2
 		}
 		}
 		bfn := d.h.getExtForTag(tag)
 		bfn := d.h.getExtForTag(tag)
@@ -1453,8 +1454,8 @@ func (d *Decoder) swallow() {
 			l := len(n.is)
 			l := len(n.is)
 			n.is = append(n.is, nil)
 			n.is = append(n.is, nil)
 			v2 := &n.is[l]
 			v2 := &n.is[l]
-			n.is = n.is[:l]
 			d.decode(v2)
 			d.decode(v2)
+			n.is = n.is[:l]
 		}
 		}
 	}
 	}
 }
 }