reflect: fix stack overflow panic when using haveIdenticalUnderlyingType

haveIdenticalUnderlyingType raises stack overflow when compares
self-referential structs having same structure in different packages.

Change-Id: I7c79ab988edcffadcf7e0730a50b4d31b136bb6a
GitHub-Last-Rev: 4d4217f0c1
GitHub-Pull-Request: golang/go#45543
Reviewed-on: https://go-review.googlesource.com/c/go/+/309729
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Jinzhu 2021-04-20 02:47:54 +00:00 committed by Ian Lance Taylor
parent fbb600b283
commit 7473a6a0eb
4 changed files with 38 additions and 1 deletions

View file

@ -15,6 +15,8 @@ import (
"math/rand"
"os"
. "reflect"
"reflect/internal/example1"
"reflect/internal/example2"
"runtime"
"sort"
"strconv"
@ -3808,6 +3810,16 @@ type Empty struct{}
type MyStruct struct {
x int `some:"tag"`
}
type MyStruct1 struct {
x struct {
int `some:"bar"`
}
}
type MyStruct2 struct {
x struct {
int `some:"foo"`
}
}
type MyString string
type MyBytes []byte
type MyRunes []int32
@ -4158,6 +4170,9 @@ var convertTests = []struct {
x int `some:"bar"`
}{}), V(MyStruct{})},
{V(MyStruct1{}), V(MyStruct2{})},
{V(MyStruct2{}), V(MyStruct1{})},
// can convert *byte and *MyByte
{V((*byte)(nil)), V((*MyByte)(nil))},
{V((*MyByte)(nil)), V((*byte)(nil))},
@ -7231,3 +7246,13 @@ func iterateToString(it *MapIter) string {
sort.Strings(got)
return "[" + strings.Join(got, ", ") + "]"
}
func TestConvertibleTo(t *testing.T) {
t1 := ValueOf(example1.MyStruct{}).Type()
t2 := ValueOf(example2.MyStruct{}).Type()
// Shouldn't raise stack overflow
if t1.ConvertibleTo(t2) {
t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t1, t2)
}
}

View file

@ -0,0 +1,6 @@
package example1
type MyStruct struct {
MyStructs []MyStruct
MyStruct *MyStruct
}

View file

@ -0,0 +1,6 @@
package example2
type MyStruct struct {
MyStructs []MyStruct
MyStruct *MyStruct
}

View file

@ -1599,7 +1599,7 @@ func haveIdenticalType(T, V Type, cmpTags bool) bool {
return T == V
}
if T.Name() != V.Name() || T.Kind() != V.Kind() {
if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() {
return false
}