Skip to content

Commit 5f89800

Browse files
committed
fixed issue of overwriting a slice
1 parent 3b5ab61 commit 5f89800

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

tt_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,12 @@ var testCases = []testCase{
576576
{3, 0, 0, 0, 18, 0, 2, 2, 4, 1, 104, 105, 2, 111, 111, 112, 115, 0, 0, 5, 18, 2, 69, 109, 98, 101, 100, 1, 3, 2, 1, 108, 111, 108, 2, 104, 105, 0},
577577
{3, 0, 0, 0, 18, 0, 2, 0, 5, 18, 2, 69, 109, 98, 101, 100, 1, 3, 2, 1, 108, 111, 108, 2, 104, 105, 0, 2, 4, 1, 104, 105, 2, 111, 111, 112, 115, 0}},
578578
},
579+
{
580+
name: "testSingleValueToInterface",
581+
data: "hello",
582+
bytes: [][]byte{
583+
{3, 0, 5, 0, 1, 104, 101, 108, 108, 111, 0, 0}},
584+
},
579585
}
580586

581587
func testStructDecode(t *testing.T, testcase testCase) {

v3.go

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type V3Encoder struct {
1717
out io.Writer
1818
varintbuf *[binary.MaxVarintLen64 + 1]byte
1919
sync.Mutex
20+
typeCache map[string]map[string]int
2021
}
2122

2223
var v3StreamHeader = []byte{version3, 1 << 7}
@@ -32,6 +33,7 @@ func NewV3Encoder(out io.Writer, isStream bool) *V3Encoder {
3233
return &V3Encoder{
3334
out: out,
3435
varintbuf: &[binary.MaxVarintLen64 + 1]byte{},
36+
typeCache: map[string]map[string]int{},
3537
}
3638
}
3739

@@ -42,6 +44,7 @@ func Encodev3(d interface{}, out io.Writer) error {
4244
enc := &V3Encoder{
4345
out: out,
4446
varintbuf: &[binary.MaxVarintLen64 + 1]byte{},
47+
typeCache: map[string]map[string]int{},
4548
}
4649
//We dont have to lock/unlock since we know we are the only one witha acces
4750
return enc.encodeValuev3(d, v3.Key{})
@@ -256,7 +259,15 @@ func (enc *V3Encoder) encodeValuev3(d interface{}, k v3.Key) error {
256259
}
257260
value.Vtype = v3.BytesT
258261
} else if kind == reflect.Struct {
259-
usableFields := getStructFields(val)
262+
name := val.Type().String()
263+
var usableFields map[string]int
264+
if v, ok := enc.typeCache[name]; ok {
265+
usableFields = v
266+
} else {
267+
usableFields = getStructFields(val)
268+
enc.typeCache[name] = usableFields
269+
}
270+
260271
value.Childrenn = uint64(len(usableFields))
261272
value.Vtype = v3.MapT
262273
alreadyEncoded = true
@@ -300,6 +311,7 @@ type V3Decoder struct {
300311
isStream bool
301312
didDecode bool
302313
in v3.Reader
314+
typeCache map[string]map[string]int
303315
sync.Mutex
304316
}
305317

@@ -308,8 +320,9 @@ type V3Decoder struct {
308320
//Initializing the decoder blocks until at least the first 2 bytes are read.
309321
func NewV3Decoder(in v3.Reader, init bool) *V3Decoder {
310322
dec := V3Decoder{
311-
didInit: !init,
312-
in: in,
323+
didInit: !init,
324+
in: in,
325+
typeCache: map[string]map[string]int{},
313326
}
314327
if init {
315328
dec.Init()
@@ -543,7 +556,7 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
543556
}
544557
case v3.Int64T:
545558
val := v3.Int64FromBytes(v.Value)
546-
if e.Kind() != reflect.Int64 || e.Kind() != reflect.Int {
559+
if e.Kind() != reflect.Int64 && e.Kind() != reflect.Int {
547560
if e.Kind() != reflect.Interface || e.Type().NumMethod() != 0 {
548561
return errors.New("TT: cannot unmarshal int64 into " + e.Kind().String() + " Go type")
549562
}
@@ -647,7 +660,7 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
647660
if v, ok := k.([]byte); ok {
648661
m[string(v)] = key.Interface()
649662
} else {
650-
m[k] = key.Interface()
663+
m[v] = key.Interface()
651664
}
652665
}
653666
e.Set(reflect.ValueOf(m))
@@ -660,9 +673,15 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
660673
}
661674

662675
var err error
663-
value := reflect.New(e.Type().Elem()).Elem()
676+
var value reflect.Value
664677
key := reflect.New(e.Type().Key()).Elem()
665678

679+
ValueKind := e.Type().Elem().Kind()
680+
shouldReplace := ValueKind == reflect.Array || ValueKind == reflect.Slice || ValueKind == reflect.Map
681+
682+
if !shouldReplace {
683+
value = reflect.New(e.Type().Elem()).Elem()
684+
}
666685
for i := uint64(0); i < children; i++ {
667686
v.FromBytes(dec.in)
668687
*yetToRead += v.Childrenn - 1
@@ -671,16 +690,26 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
671690
if err != nil {
672691
return err
673692
}
693+
if shouldReplace {
694+
value = reflect.New(e.Type().Elem()).Elem()
695+
}
674696
err = dec.decodeValuev3(v, value, yetToRead)
675697
if err != nil {
676698
return err
677699
}
678-
679700
e.SetMapIndex(key, value)
680701
}
681702
} else if e.Kind() == reflect.Struct {
703+
682704
children := v.Childrenn
683-
usableFields := getStructFields(e)
705+
name := e.Type().String()
706+
var usableFields map[string]int
707+
if v, ok := dec.typeCache[name]; ok {
708+
usableFields = v
709+
} else {
710+
usableFields = getStructFields(e)
711+
dec.typeCache[name] = usableFields
712+
}
684713

685714
for i := uint64(0); i < children; i++ {
686715
v.FromBytes(dec.in)
@@ -727,6 +756,8 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
727756
len := e.Len()
728757
if len < int(children) {
729758
e.Set(reflect.MakeSlice(e.Type(), int(children), int(children)))
759+
} else if len > int(children) {
760+
e.SetLen(int(children))
730761
}
731762
for i := 0; i < int(children); i++ {
732763
v.FromBytes(dec.in)
@@ -745,11 +776,19 @@ func (dec *V3Decoder) decodeValuev3(v v3.Value, e reflect.Value, yetToRead *uint
745776
//if all special cases fail we fall back to []interface{}
746777
arr := make([]interface{}, children)
747778
var err error
748-
value := reflect.New(reflect.TypeOf(arr).Elem()).Elem()
779+
var value reflect.Value
780+
ValueKind := e.Type().Elem().Kind()
781+
shouldReplace := ValueKind == reflect.Array || ValueKind == reflect.Slice || ValueKind == reflect.Map
749782

783+
if !shouldReplace {
784+
value = reflect.New(e.Type().Elem()).Elem()
785+
}
750786
for i := 0; i < int(children); i++ {
751787
v.FromBytes(dec.in)
752788
*yetToRead += v.Childrenn - 1
789+
if shouldReplace {
790+
value = reflect.New(e.Type().Elem()).Elem()
791+
}
753792

754793
err = dec.decodeValuev3(v, value, yetToRead)
755794
if err != nil {

0 commit comments

Comments
 (0)