]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: fix method indexing for non-ASCII exported methods
authorMatthew Dempsky <mdempsky@google.com>
Thu, 28 Sep 2017 03:14:54 +0000 (20:14 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 28 Sep 2017 18:06:53 +0000 (18:06 +0000)
Currently, methods are sorted by name. This happens to guarantee that
exported ASCII methods appear before non-exported ASCII methods, but
this breaks down when Unicode method names are considered.

Type.Method already accounts for this by always indexing into the
slice returned by exportedMethods. This CL makes Value.Method do the
same.

Fixes #22073.

Change-Id: I9bfc6bbfb7353e0bd3c439a15d1c3da60d16d209
Reviewed-on: https://go-review.googlesource.com/66770
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/reflect/all_test.go
src/reflect/value.go

index b101818519a5985b72e04a1e007081c69e994639..efa9fe13d23520fbd3a87f0deccdb152fe49c83b 100644 (file)
@@ -6405,3 +6405,19 @@ func TestIssue22031(t *testing.T) {
                }
        }
 }
+
+type NonExportedFirst int
+
+func (i NonExportedFirst) ΦExported()       {}
+func (i NonExportedFirst) nonexported() int { panic("wrong") }
+
+func TestIssue22073(t *testing.T) {
+       m := ValueOf(NonExportedFirst(0)).Method(0)
+
+       if got := m.Type().NumOut(); got != 0 {
+               t.Errorf("NumOut: got %v, want 0", got)
+       }
+
+       // Shouldn't panic.
+       m.Call(nil)
+}
index 91b0e37f509e3a7722a36d5005136037086442a9..e9bfe550f4c3b1cc2fa2e5a0e8bf8fbbae6c77f2 100644 (file)
@@ -584,11 +584,11 @@ func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn
                t = tt.typeOff(m.typ)
        } else {
                rcvrtype = v.typ
-               ut := v.typ.uncommon()
-               if ut == nil || uint(i) >= uint(ut.mcount) {
+               ms := v.typ.exportedMethods()
+               if uint(i) >= uint(len(ms)) {
                        panic("reflect: internal error: invalid method index")
                }
-               m := ut.methods()[i]
+               m := ms[i]
                if !v.typ.nameOff(m.name).isExported() {
                        panic("reflect: " + op + " of unexported method")
                }
@@ -1717,11 +1717,11 @@ func (v Value) Type() Type {
                return v.typ.typeOff(m.typ)
        }
        // Method on concrete type.
-       ut := v.typ.uncommon()
-       if ut == nil || uint(i) >= uint(ut.mcount) {
+       ms := v.typ.exportedMethods()
+       if uint(i) >= uint(len(ms)) {
                panic("reflect: internal error: invalid method index")
        }
-       m := ut.methods()[i]
+       m := ms[i]
        return v.typ.typeOff(m.mtyp)
 }