-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix panic using ArgsFlat or ScanStruct on structs with nil Anonymous field pointers. Also: * Remove unused travis-ci link from README. * Rename goXX.go to be functionality specific. Fixes: #621
- Loading branch information
Showing
8 changed files
with
220 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package redis | ||
|
||
import ( | ||
"reflect" | ||
"runtime" | ||
) | ||
|
||
// methodName returns the name of the calling method, | ||
// assumed to be two stack frames above. | ||
func methodName() string { | ||
pc, _, _, _ := runtime.Caller(2) | ||
f := runtime.FuncForPC(pc) | ||
if f == nil { | ||
return "unknown method" | ||
} | ||
return f.Name() | ||
} | ||
|
||
// mustBe panics if f's kind is not expected. | ||
func mustBe(v reflect.Value, expected reflect.Kind) { | ||
if v.Kind() != expected { | ||
panic(&reflect.ValueError{Method: methodName(), Kind: v.Kind()}) | ||
} | ||
} | ||
|
||
// fieldByIndexCreate returns the nested field corresponding | ||
// to index creating elements that are nil when stepping through. | ||
// It panics if v is not a struct. | ||
func fieldByIndexCreate(v reflect.Value, index []int) reflect.Value { | ||
if len(index) == 1 { | ||
return v.Field(index[0]) | ||
} | ||
|
||
mustBe(v, reflect.Struct) | ||
for i, x := range index { | ||
if i > 0 { | ||
if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct { | ||
if v.IsNil() { | ||
v.Set(reflect.New(v.Type().Elem())) | ||
} | ||
v = v.Elem() | ||
} | ||
} | ||
v = v.Field(x) | ||
} | ||
|
||
return v | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//go:build go1.17 && !go1.18 | ||
// +build go1.17,!go1.18 | ||
|
||
package redis | ||
|
||
import ( | ||
"errors" | ||
"reflect" | ||
) | ||
|
||
// fieldByIndexErr returns the nested field corresponding to index. | ||
// It returns an error if evaluation requires stepping through a nil | ||
// pointer, but panics if it must step through a field that | ||
// is not a struct. | ||
func fieldByIndexErr(v reflect.Value, index []int) (reflect.Value, error) { | ||
if len(index) == 1 { | ||
return v.Field(index[0]), nil | ||
} | ||
|
||
mustBe(v, reflect.Struct) | ||
for i, x := range index { | ||
if i > 0 { | ||
if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct { | ||
if v.IsNil() { | ||
return reflect.Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + v.Type().Elem().Name()) | ||
} | ||
v = v.Elem() | ||
} | ||
} | ||
v = v.Field(x) | ||
} | ||
|
||
return v, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//go:build go1.18 | ||
// +build go1.18 | ||
|
||
package redis | ||
|
||
import ( | ||
"reflect" | ||
) | ||
|
||
// fieldByIndexErr returns the nested field corresponding to index. | ||
// It returns an error if evaluation requires stepping through a nil | ||
// pointer, but panics if it must step through a field that | ||
// is not a struct. | ||
func fieldByIndexErr(v reflect.Value, index []int) (reflect.Value, error) { | ||
return v.FieldByIndexErr(index) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
//go:build go1.7 && !go1.8 | ||
// +build go1.7,!go1.8 | ||
|
||
package redis | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
//go:build go1.8 | ||
// +build go1.8 | ||
|
||
package redis | ||
|