1
0
mirror of https://github.com/golang/go synced 2024-11-17 16:04:47 -07:00

errors: fix Is panics if target is uncomparable

Fixes #31841

Change-Id: I3f068686154fd2fa5755b0df47b4eaa5c9a19107
Reviewed-on: https://go-review.googlesource.com/c/go/+/175260
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
LE Manh Cuong 2019-05-05 23:20:26 +07:00 committed by Brad Fitzpatrick
parent 79f79c34de
commit 0bf1f02ed9
2 changed files with 22 additions and 1 deletions

View File

@ -51,8 +51,10 @@ func Is(err, target error) bool {
if target == nil { if target == nil {
return err == target return err == target
} }
isComparable := target == nil || reflectlite.TypeOf(target).Comparable()
for { for {
if err == target { if isComparable && err == target {
return true return true
} }
if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {

View File

@ -47,6 +47,12 @@ func TestIs(t *testing.T) {
{poser, errb, false}, {poser, errb, false},
{poser, erro, false}, {poser, erro, false},
{poser, errco, false}, {poser, errco, false},
{errorUncomparable{}, errorUncomparable{}, true},
{errorUncomparable{}, &errorUncomparable{}, false},
{&errorUncomparable{}, errorUncomparable{}, true},
{&errorUncomparable{}, &errorUncomparable{}, false},
{errorUncomparable{}, err1, false},
{&errorUncomparable{}, err1, false},
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
@ -260,3 +266,16 @@ type printer struct {
} }
func (p *printer) Print(args ...interface{}) { fmt.Fprint(&p.buf, args...) } func (p *printer) Print(args ...interface{}) { fmt.Fprint(&p.buf, args...) }
type errorUncomparable struct {
f []string
}
func (errorUncomparable) Error() string {
return "uncomparable error"
}
func (errorUncomparable) Is(target error) bool {
_, ok := target.(errorUncomparable)
return ok
}