Skip to content

Commit 27df231

Browse files
monkey92tMonkey
andauthored
hscan adds support for i386 platform (#1652)
* hscan adds support for i386 platform Signed-off-by: monkey <[email protected]> * update go.sum Signed-off-by: monkey <[email protected]> * detect overflow of scan Signed-off-by: monkey <[email protected]> * restore the return value type of decoderFunc to error Signed-off-by: monkey <[email protected]> * fix clean Signed-off-by: monkey <[email protected]> * fix clean Signed-off-by: monkey <[email protected]> Co-authored-by: Monkey <[email protected]>
1 parent fd6fac1 commit 27df231

File tree

4 files changed

+156
-41
lines changed

4 files changed

+156
-41
lines changed

go.sum

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
2525
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
2626
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
2727
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
28-
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
29-
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
28+
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
3029
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
3130
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
3231
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
33-
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
34-
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
32+
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
3533
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
3634
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3735
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -62,12 +60,11 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
6260
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6361
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6462
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
65-
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6663
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
6764
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
65+
golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
6866
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6967
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
70-
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
7168
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
7269
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
7370
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -77,6 +74,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
7774
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
7875
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
7976
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
77+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
8078
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
8179
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
8280
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

internal/hscan/hscan.go

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ var (
1515
decoders = []decoderFunc{
1616
reflect.Bool: decodeBool,
1717
reflect.Int: decodeInt,
18-
reflect.Int8: decodeInt,
19-
reflect.Int16: decodeInt,
20-
reflect.Int32: decodeInt,
21-
reflect.Int64: decodeInt,
18+
reflect.Int8: decodeInt8,
19+
reflect.Int16: decodeInt16,
20+
reflect.Int32: decodeInt32,
21+
reflect.Int64: decodeInt64,
2222
reflect.Uint: decodeUint,
23-
reflect.Uint8: decodeUint,
24-
reflect.Uint16: decodeUint,
25-
reflect.Uint32: decodeUint,
26-
reflect.Uint64: decodeUint,
27-
reflect.Float32: decodeFloat,
28-
reflect.Float64: decodeFloat,
23+
reflect.Uint8: decodeUint8,
24+
reflect.Uint16: decodeUint16,
25+
reflect.Uint32: decodeUint32,
26+
reflect.Uint64: decodeUint64,
27+
reflect.Float32: decodeFloat32,
28+
reflect.Float64: decodeFloat64,
2929
reflect.Complex64: decodeUnsupported,
3030
reflect.Complex128: decodeUnsupported,
3131
reflect.Array: decodeUnsupported,
@@ -106,26 +106,76 @@ func decodeBool(f reflect.Value, s string) error {
106106
return nil
107107
}
108108

109+
func decodeInt8(f reflect.Value, s string) error {
110+
return decodeNumber(f, s, 8)
111+
}
112+
113+
func decodeInt16(f reflect.Value, s string) error {
114+
return decodeNumber(f, s, 16)
115+
}
116+
117+
func decodeInt32(f reflect.Value, s string) error {
118+
return decodeNumber(f, s, 32)
119+
}
120+
121+
func decodeInt64(f reflect.Value, s string) error {
122+
return decodeNumber(f, s, 64)
123+
}
124+
109125
func decodeInt(f reflect.Value, s string) error {
110-
v, err := strconv.ParseInt(s, 10, 0)
126+
return decodeNumber(f, s, 0)
127+
}
128+
129+
func decodeNumber(f reflect.Value, s string, bitSize int) error {
130+
v, err := strconv.ParseInt(s, 10, bitSize)
111131
if err != nil {
112132
return err
113133
}
114134
f.SetInt(v)
115135
return nil
116136
}
117137

138+
func decodeUint8(f reflect.Value, s string) error {
139+
return decodeUnsignedNumber(f, s, 8)
140+
}
141+
142+
func decodeUint16(f reflect.Value, s string) error {
143+
return decodeUnsignedNumber(f, s, 16)
144+
}
145+
146+
func decodeUint32(f reflect.Value, s string) error {
147+
return decodeUnsignedNumber(f, s, 32)
148+
}
149+
150+
func decodeUint64(f reflect.Value, s string) error {
151+
return decodeUnsignedNumber(f, s, 64)
152+
}
153+
118154
func decodeUint(f reflect.Value, s string) error {
119-
v, err := strconv.ParseUint(s, 10, 0)
155+
return decodeUnsignedNumber(f, s, 0)
156+
}
157+
158+
func decodeUnsignedNumber(f reflect.Value, s string, bitSize int) error {
159+
v, err := strconv.ParseUint(s, 10, bitSize)
120160
if err != nil {
121161
return err
122162
}
123163
f.SetUint(v)
124164
return nil
125165
}
126166

127-
func decodeFloat(f reflect.Value, s string) error {
128-
v, err := strconv.ParseFloat(s, 0)
167+
func decodeFloat32(f reflect.Value, s string) error {
168+
v, err := strconv.ParseFloat(s, 32)
169+
if err != nil {
170+
return err
171+
}
172+
f.SetFloat(v)
173+
return nil
174+
}
175+
176+
// although the default is float64, but we better define it.
177+
func decodeFloat64(f reflect.Value, s string) error {
178+
v, err := strconv.ParseFloat(s, 64)
129179
if err != nil {
130180
return err
131181
}

internal/hscan/hscan_test.go

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package hscan
22

33
import (
4+
"math"
5+
"strconv"
46
"testing"
57

68
. "github.com/onsi/ginkgo"
@@ -11,12 +13,21 @@ type data struct {
1113
Omit string `redis:"-"`
1214
Empty string
1315

14-
String string `redis:"string"`
15-
Bytes []byte `redis:"byte"`
16-
Int int `redis:"int"`
17-
Uint uint `redis:"uint"`
18-
Float float32 `redis:"float"`
19-
Bool bool `redis:"bool"`
16+
String string `redis:"string"`
17+
Bytes []byte `redis:"byte"`
18+
Int int `redis:"int"`
19+
Int8 int8 `redis:"int8"`
20+
Int16 int16 `redis:"int16"`
21+
Int32 int32 `redis:"int32"`
22+
Int64 int64 `redis:"int64"`
23+
Uint uint `redis:"uint"`
24+
Uint8 uint8 `redis:"uint8"`
25+
Uint16 uint16 `redis:"uint16"`
26+
Uint32 uint32 `redis:"uint32"`
27+
Uint64 uint64 `redis:"uint64"`
28+
Float float32 `redis:"float"`
29+
Float64 float64 `redis:"float64"`
30+
Bool bool `redis:"bool"`
2031
}
2132

2233
type i []interface{}
@@ -43,23 +54,70 @@ var _ = Describe("Scan", func() {
4354
Expect(Scan(data{}, i{"key", "string"}, i{nil, nil})).To(HaveOccurred())
4455
})
4556

57+
It("number out of range", func() {
58+
f := func(v uint64) string {
59+
return strconv.FormatUint(v, 10) + "1"
60+
}
61+
keys := i{"int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "float64"}
62+
vals := i{
63+
f(math.MaxInt8), f(math.MaxInt16), f(math.MaxInt32), f(math.MaxInt64),
64+
f(math.MaxUint8), f(math.MaxUint16), f(math.MaxUint32), strconv.FormatUint(math.MaxUint64, 10) + "1",
65+
"13.4028234663852886e+38", "11.79769313486231570e+308",
66+
}
67+
for k, v := range keys {
68+
var d data
69+
Expect(Scan(&d, i{v}, i{vals[k]})).To(HaveOccurred())
70+
}
71+
72+
//success
73+
f = func(v uint64) string {
74+
return strconv.FormatUint(v, 10)
75+
}
76+
keys = i{"int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "float64"}
77+
vals = i{
78+
f(math.MaxInt8), f(math.MaxInt16), f(math.MaxInt32), f(math.MaxInt64),
79+
f(math.MaxUint8), f(math.MaxUint16), f(math.MaxUint32), strconv.FormatUint(math.MaxUint64, 10),
80+
"3.40282346638528859811704183484516925440e+38", "1.797693134862315708145274237317043567981e+308",
81+
}
82+
var d data
83+
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
84+
Expect(d).To(Equal(data{
85+
Int8: math.MaxInt8,
86+
Int16: math.MaxInt16,
87+
Int32: math.MaxInt32,
88+
Int64: math.MaxInt64,
89+
Uint8: math.MaxUint8,
90+
Uint16: math.MaxUint16,
91+
Uint32: math.MaxUint32,
92+
Uint64: math.MaxUint64,
93+
Float: math.MaxFloat32,
94+
Float64: math.MaxFloat64,
95+
}))
96+
})
97+
4698
It("scans good values", func() {
4799
var d data
48100

49101
// non-tagged fields.
50102
Expect(Scan(&d, i{"key"}, i{"value"})).NotTo(HaveOccurred())
51103
Expect(d).To(Equal(data{}))
52104

53-
keys := i{"string", "byte", "int", "uint", "float", "bool"}
54-
vals := i{"str!", "bytes!", "123", "456", "123.456", "1"}
105+
keys := i{"string", "byte", "int", "int64", "uint", "uint64", "float", "float64", "bool"}
106+
vals := i{
107+
"str!", "bytes!", "123", "123456789123456789", "456", "987654321987654321",
108+
"123.456", "123456789123456789.987654321987654321", "1",
109+
}
55110
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
56111
Expect(d).To(Equal(data{
57-
String: "str!",
58-
Bytes: []byte("bytes!"),
59-
Int: 123,
60-
Uint: 456,
61-
Float: 123.456,
62-
Bool: true,
112+
String: "str!",
113+
Bytes: []byte("bytes!"),
114+
Int: 123,
115+
Int64: 123456789123456789,
116+
Uint: 456,
117+
Uint64: 987654321987654321,
118+
Float: 123.456,
119+
Float64: 1.2345678912345678e+17,
120+
Bool: true,
63121
}))
64122

65123
// Scan a different type with the same values to test that
@@ -85,12 +143,15 @@ var _ = Describe("Scan", func() {
85143

86144
Expect(Scan(&d, i{"string", "float", "bool"}, i{"", "1", "t"})).NotTo(HaveOccurred())
87145
Expect(d).To(Equal(data{
88-
String: "",
89-
Bytes: []byte("bytes!"),
90-
Int: 123,
91-
Uint: 456,
92-
Float: 1.0,
93-
Bool: true,
146+
String: "",
147+
Bytes: []byte("bytes!"),
148+
Int: 123,
149+
Int64: 123456789123456789,
150+
Uint: 456,
151+
Uint64: 987654321987654321,
152+
Float: 1.0,
153+
Float64: 1.2345678912345678e+17,
154+
Bool: true,
94155
}))
95156
})
96157

internal/hscan/structmap.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package hscan
22

33
import (
4+
"fmt"
45
"reflect"
56
"strings"
67
"sync"
@@ -83,5 +84,10 @@ func (s StructValue) Scan(key string, value string) error {
8384
if !ok {
8485
return nil
8586
}
86-
return field.fn(s.value.Field(field.index), value)
87+
if err := field.fn(s.value.Field(field.index), value); err != nil {
88+
t := s.value.Type()
89+
return fmt.Errorf("cannot scan redis.result %s into struct field %s.%s of type %s, error-%s",
90+
value, t.Name(), t.Field(field.index).Name, t.Field(field.index).Type, err.Error())
91+
}
92+
return nil
8793
}

0 commit comments

Comments
 (0)