Skip to content

Commit 36b43bb

Browse files
committed
msgpack: fix number types conversions after decoding
msgpack v2.9.2 decodes all numbers as uint[1] or int[2], but msgpack.v5 decodes numbers as a MessagePack type[3]. We need to unify the type conversions in the code. 1. https://github.com/vmihailenco/msgpack/blob/23644a15054d8b9f8a9fca3e041f3419504b9c21/decode.go#L283 2. https://github.com/vmihailenco/msgpack/blob/23644a15054d8b9f8a9fca3e041f3419504b9c21/decode.go#L285 3. https://github.com/vmihailenco/msgpack/blob/233c977ae92b215a9aa7eb420bbe67da99f05ab6/decode.go#L410 Part of #124
1 parent e2c68d7 commit 36b43bb

File tree

2 files changed

+77
-11
lines changed

2 files changed

+77
-11
lines changed

queue/queue.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,40 @@ func (q *queue) produce(cmd string, params ...interface{}) (string, error) {
283283
return qd.task.status, nil
284284
}
285285

286+
func convertUint64(v interface{}) (result uint64, err error) {
287+
switch v := v.(type) {
288+
case uint:
289+
result = uint64(v)
290+
case uint8:
291+
result = uint64(v)
292+
case uint16:
293+
result = uint64(v)
294+
case uint32:
295+
result = uint64(v)
296+
case uint64:
297+
result = uint64(v)
298+
case int:
299+
result = uint64(v)
300+
case int8:
301+
result = uint64(v)
302+
case int16:
303+
result = uint64(v)
304+
case int32:
305+
result = uint64(v)
306+
case int64:
307+
result = uint64(v)
308+
default:
309+
err = fmt.Errorf("Non-number value %T", v)
310+
}
311+
return
312+
}
313+
286314
// Reverse the effect of a bury request on one or more tasks.
287315
func (q *queue) Kick(count uint64) (uint64, error) {
288316
resp, err := q.conn.Call(q.cmds.kick, []interface{}{count})
289317
var id uint64
290318
if err == nil {
291-
id = resp.Data[0].([]interface{})[0].(uint64)
319+
id, err = convertUint64(resp.Data[0].([]interface{})[0])
292320
}
293321
return id, err
294322
}

tarantool_test.go

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ func (m *Member) decodeMsgpackImpl(d *Decoder) error {
5252
return nil
5353
}
5454

55+
func convertUint64(v interface{}) (result uint64, err error) {
56+
switch v := v.(type) {
57+
case uint:
58+
result = uint64(v)
59+
case uint8:
60+
result = uint64(v)
61+
case uint16:
62+
result = uint64(v)
63+
case uint32:
64+
result = uint64(v)
65+
case uint64:
66+
result = uint64(v)
67+
case int:
68+
result = uint64(v)
69+
case int8:
70+
result = uint64(v)
71+
case int16:
72+
result = uint64(v)
73+
case int32:
74+
result = uint64(v)
75+
case int64:
76+
result = uint64(v)
77+
default:
78+
err = fmt.Errorf("Non-number value %T", v)
79+
}
80+
return
81+
}
82+
5583
var server = "127.0.0.1:3013"
5684
var spaceNo = uint32(517)
5785
var spaceName = "test"
@@ -524,7 +552,7 @@ func TestClient(t *testing.T) {
524552
if len(tpl) != 3 {
525553
t.Errorf("Unexpected body of Insert (tuple len)")
526554
}
527-
if id, ok := tpl[0].(uint64); !ok || id != 1 {
555+
if id, err := convertUint64(tpl[0]); err != nil || id != 1 {
528556
t.Errorf("Unexpected body of Insert (0)")
529557
}
530558
if h, ok := tpl[1].(string); !ok || h != "hello" {
@@ -557,7 +585,7 @@ func TestClient(t *testing.T) {
557585
if len(tpl) != 3 {
558586
t.Errorf("Unexpected body of Delete (tuple len)")
559587
}
560-
if id, ok := tpl[0].(uint64); !ok || id != 1 {
588+
if id, err := convertUint64(tpl[0]); err != nil || id != 1 {
561589
t.Errorf("Unexpected body of Delete (0)")
562590
}
563591
if h, ok := tpl[1].(string); !ok || h != "hello" {
@@ -599,7 +627,7 @@ func TestClient(t *testing.T) {
599627
if len(tpl) != 3 {
600628
t.Errorf("Unexpected body of Replace (tuple len)")
601629
}
602-
if id, ok := tpl[0].(uint64); !ok || id != 2 {
630+
if id, err := convertUint64(tpl[0]); err != nil || id != 2 {
603631
t.Errorf("Unexpected body of Replace (0)")
604632
}
605633
if h, ok := tpl[1].(string); !ok || h != "hi" {
@@ -624,7 +652,7 @@ func TestClient(t *testing.T) {
624652
if len(tpl) != 2 {
625653
t.Errorf("Unexpected body of Update (tuple len)")
626654
}
627-
if id, ok := tpl[0].(uint64); !ok || id != 2 {
655+
if id, err := convertUint64(tpl[0]); err != nil || id != 2 {
628656
t.Errorf("Unexpected body of Update (0)")
629657
}
630658
if h, ok := tpl[1].(string); !ok || h != "bye" {
@@ -673,7 +701,7 @@ func TestClient(t *testing.T) {
673701
if tpl, ok := resp.Data[0].([]interface{}); !ok {
674702
t.Errorf("Unexpected body of Select")
675703
} else {
676-
if id, ok := tpl[0].(uint64); !ok || id != 10 {
704+
if id, err := convertUint64(tpl[0]); err != nil || id != 10 {
677705
t.Errorf("Unexpected body of Select (0)")
678706
}
679707
if h, ok := tpl[1].(string); !ok || h != "val 10" {
@@ -768,15 +796,15 @@ func TestClient(t *testing.T) {
768796
if err != nil {
769797
t.Errorf("Failed to use Call")
770798
}
771-
if resp.Data[0].([]interface{})[0].(uint64) != 2 {
799+
if val, err := convertUint64(resp.Data[0].([]interface{})[0]); err != nil || val != 2 {
772800
t.Errorf("result is not {{1}} : %v", resp.Data)
773801
}
774802

775803
resp, err = conn.Call17("simple_incr", []interface{}{1})
776804
if err != nil {
777805
t.Errorf("Failed to use Call17")
778806
}
779-
if resp.Data[0].(uint64) != 2 {
807+
if val, err := convertUint64(resp.Data[0]); err != nil || val != 2 {
780808
t.Errorf("result is not {{1}} : %v", resp.Data)
781809
}
782810

@@ -791,8 +819,7 @@ func TestClient(t *testing.T) {
791819
if len(resp.Data) < 1 {
792820
t.Errorf("Response.Data is empty after Eval")
793821
}
794-
val := resp.Data[0].(uint64)
795-
if val != 11 {
822+
if val, err := convertUint64(resp.Data[0]); err != nil || val != 11 {
796823
t.Errorf("5 + 6 == 11, but got %v", val)
797824
}
798825
}
@@ -984,7 +1011,18 @@ func TestSQL(t *testing.T) {
9841011
assert.NoError(t, err, "Failed to Execute, Query number: %d", i)
9851012
assert.NotNil(t, resp, "Response is nil after Execute\nQuery number: %d", i)
9861013
for j := range resp.Data {
987-
assert.Equal(t, resp.Data[j], test.Resp.Data[j], "Response data is wrong")
1014+
fixed := make([]interface{}, 0)
1015+
1016+
assert.EqualValues(t, reflect.TypeOf(resp.Data[j]).Kind(), reflect.Slice)
1017+
s := reflect.ValueOf(resp.Data[j])
1018+
for k := 0; k < s.Len(); k++ {
1019+
val := s.Index(k)
1020+
if num, err := convertUint64(val.Interface()); err == nil {
1021+
val = reflect.ValueOf(num)
1022+
}
1023+
fixed = append(fixed, val.Interface())
1024+
}
1025+
assert.Equal(t, fixed, test.Resp.Data[j], "Response data is wrong")
9881026
}
9891027
assert.Equal(t, resp.SQLInfo.AffectedCount, test.Resp.SQLInfo.AffectedCount, "Affected count is wrong")
9901028

0 commit comments

Comments
 (0)