]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: fix stack overflow panic when using haveIdenticalUnderlyingType
authorJinzhu <wosmvp@gmail.com>
Tue, 20 Apr 2021 02:47:54 +0000 (02:47 +0000)
committerIan Lance Taylor <iant@golang.org>
Tue, 20 Apr 2021 20:14:14 +0000 (20:14 +0000)
haveIdenticalUnderlyingType raises stack overflow when compares
self-referential structs having same structure in different packages.

Change-Id: I7c79ab988edcffadcf7e0730a50b4d31b136bb6a
GitHub-Last-Rev: 4d4217f0c16ef14aa1f38ff7cf88c98755bb8ddd
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>
src/reflect/all_test.go
src/reflect/internal/example1/example.go [new file with mode: 0644]
src/reflect/internal/example2/example.go [new file with mode: 0644]
src/reflect/type.go

index 241f6b0b5ad527d41e3ded111bde55209d0e9aca..3269f5ffcea76a501ab74cd6451f56042999f08e 100644 (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)
+       }
+}
diff --git a/src/reflect/internal/example1/example.go b/src/reflect/internal/example1/example.go
new file mode 100644 (file)
index 0000000..0f829a8
--- /dev/null
@@ -0,0 +1,6 @@
+package example1
+
+type MyStruct struct {
+       MyStructs []MyStruct
+       MyStruct  *MyStruct
+}
diff --git a/src/reflect/internal/example2/example.go b/src/reflect/internal/example2/example.go
new file mode 100644 (file)
index 0000000..df64ba1
--- /dev/null
@@ -0,0 +1,6 @@
+package example2
+
+type MyStruct struct {
+       MyStructs []MyStruct
+       MyStruct  *MyStruct
+}
index c213b31941282cb0f33b73a8d02ce8e4ae0a7543..d50559e9339d83425a4ce47ec468fcb802aff4ca 100644 (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
        }