]> Cypherpunks repositories - gostls13.git/commitdiff
errors: fix Is panics if target is uncomparable
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Sun, 5 May 2019 16:20:26 +0000 (23:20 +0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 6 May 2019 17:02:59 +0000 (17:02 +0000)
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>

src/errors/wrap.go
src/errors/wrap_test.go

index 04ddf79ba3e139225da5fb4d64be4b5dcd1005b1..69dd9464ec8e037891d2ec5079f06056da983fbd 100644 (file)
@@ -51,8 +51,10 @@ func Is(err, target error) bool {
        if target == nil {
                return err == target
        }
+
+       isComparable := target == nil || reflectlite.TypeOf(target).Comparable()
        for {
-               if err == target {
+               if isComparable && err == target {
                        return true
                }
                if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
index 022f429c0c7427667f0385b7c2250bb6b4bf833f..f8e907cff71b8716a6f63c50786faecae8012d73 100644 (file)
@@ -47,6 +47,12 @@ func TestIs(t *testing.T) {
                {poser, errb, false},
                {poser, erro, 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 {
                t.Run("", func(t *testing.T) {
@@ -260,3 +266,16 @@ type printer struct {
 }
 
 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
+}