]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: handle types with unexported methods before exported ones
authorAndré Carvalho <asantostc@gmail.com>
Fri, 28 Jul 2017 23:31:20 +0000 (20:31 -0300)
committerIan Lance Taylor <iant@golang.org>
Wed, 23 Aug 2017 23:48:49 +0000 (23:48 +0000)
The method Method expects index to be an index of exported fields,
but, before this change, the index used by MethodByName could
take into account unexported fields if those happened sort
before the exported one.

Fixes #21177

Change-Id: I90bb64a47b23e2e43fdd2b8a1e0a2c9a8a63ded2
Reviewed-on: https://go-review.googlesource.com/51810
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/reflect/all_test.go
src/reflect/type.go

index 5a5c91b7512037d06edeb1fdaa98297bc9616e42..962c326c036ae8ee91ff5691792055f3c4ddd6b1 100644 (file)
@@ -5521,6 +5521,25 @@ func TestKeepFuncLive(t *testing.T) {
        MakeFunc(typ, f).Call([]Value{ValueOf(10)})
 }
 
+type UnExportedFirst int
+
+func (i UnExportedFirst) ΦExported()  {}
+func (i UnExportedFirst) unexported() {}
+
+// Issue 21177
+func TestMethodByNameUnExportedFirst(t *testing.T) {
+       defer func() {
+               if recover() != nil {
+                       t.Errorf("should not panic")
+               }
+       }()
+       typ := TypeOf(UnExportedFirst(0))
+       m, _ := typ.MethodByName("ΦExported")
+       if m.Name != "ΦExported" {
+               t.Errorf("got %s, expected ΦExported", m.Name)
+       }
+}
+
 // Issue 18635 (method version).
 type KeepMethodLive struct{}
 
index dbb65f14bf36eeb52109c91bcc491e7fb56e35a7..9f02219c8e90e8895f422a63629e9532e7c125af 100644 (file)
@@ -871,11 +871,15 @@ func (t *rtype) MethodByName(name string) (m Method, ok bool) {
                return Method{}, false
        }
        utmethods := ut.methods()
+       var eidx int
        for i := 0; i < int(ut.mcount); i++ {
                p := utmethods[i]
                pname := t.nameOff(p.name)
-               if pname.isExported() && pname.name() == name {
-                       return t.Method(i), true
+               if pname.isExported() {
+                       if pname.name() == name {
+                               return t.Method(eidx), true
+                       }
+                       eidx++
                }
        }
        return Method{}, false