Pārlūkot izejas kodu

remove panic in ScanStruct

Gary Burd 12 gadi atpakaļ
vecāks
revīzija
fe36254579
2 mainītis faili ar 27 papildinājumiem un 1 dzēšanām
  1. 6 1
      redis/scan.go
  2. 21 0
      redis/scan_test.go

+ 6 - 1
redis/scan.go

@@ -314,6 +314,8 @@ func structSpecForType(t reflect.Type) *structSpec {
 	return ss
 }
 
+var scanStructValueError = errors.New("redigo: ScanStruct value must be non-nil pointer to a struct.")
+
 // ScanStruct scans a multi-bulk src containing alternating names and values to
 // a struct. The HGETALL and CONFIG GET commands return replies in this format.
 //
@@ -333,9 +335,12 @@ func structSpecForType(t reflect.Type) *structSpec {
 func ScanStruct(src []interface{}, dest interface{}) error {
 	d := reflect.ValueOf(dest)
 	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errors.New("redigo: ScanStruct value must be non-nil pointer")
+		return scanStructValueError
 	}
 	d = d.Elem()
+	if d.Kind() != reflect.Struct {
+		return scanStructValueError
+	}
 	ss := structSpecForType(d.Type())
 
 	if len(src)%2 != 0 {

+ 21 - 0
redis/scan_test.go

@@ -183,6 +183,27 @@ func TestScanStruct(t *testing.T) {
 	}
 }
 
+func TestBadScanStructArgs(t *testing.T) {
+	x := []interface{}{"A", "b"}
+	test := func(v interface{}) {
+		if err := redis.ScanStruct(x, v); err == nil {
+			t.Errorf("Expect error for ScanStruct(%T, %T)", x, v)
+		}
+	}
+
+	test(nil)
+
+	var v0 *struct{}
+	test(v0)
+
+	var v1 int
+	test(&v1)
+
+	x = x[:1]
+	v2 := struct{ A string }{}
+	test(&v2)
+}
+
 var argsTests = []struct {
 	title    string
 	actual   redis.Args