mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
fbb600b283
commit
7473a6a0eb
4 changed files with 38 additions and 1 deletions
|
|
@ -15,6 +15,8 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
. "reflect"
|
. "reflect"
|
||||||
|
"reflect/internal/example1"
|
||||||
|
"reflect/internal/example2"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -3808,6 +3810,16 @@ type Empty struct{}
|
||||||
type MyStruct struct {
|
type MyStruct struct {
|
||||||
x int `some:"tag"`
|
x int `some:"tag"`
|
||||||
}
|
}
|
||||||
|
type MyStruct1 struct {
|
||||||
|
x struct {
|
||||||
|
int `some:"bar"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type MyStruct2 struct {
|
||||||
|
x struct {
|
||||||
|
int `some:"foo"`
|
||||||
|
}
|
||||||
|
}
|
||||||
type MyString string
|
type MyString string
|
||||||
type MyBytes []byte
|
type MyBytes []byte
|
||||||
type MyRunes []int32
|
type MyRunes []int32
|
||||||
|
|
@ -4158,6 +4170,9 @@ var convertTests = []struct {
|
||||||
x int `some:"bar"`
|
x int `some:"bar"`
|
||||||
}{}), V(MyStruct{})},
|
}{}), V(MyStruct{})},
|
||||||
|
|
||||||
|
{V(MyStruct1{}), V(MyStruct2{})},
|
||||||
|
{V(MyStruct2{}), V(MyStruct1{})},
|
||||||
|
|
||||||
// can convert *byte and *MyByte
|
// can convert *byte and *MyByte
|
||||||
{V((*byte)(nil)), V((*MyByte)(nil))},
|
{V((*byte)(nil)), V((*MyByte)(nil))},
|
||||||
{V((*MyByte)(nil)), V((*byte)(nil))},
|
{V((*MyByte)(nil)), V((*byte)(nil))},
|
||||||
|
|
@ -7231,3 +7246,13 @@ func iterateToString(it *MapIter) string {
|
||||||
sort.Strings(got)
|
sort.Strings(got)
|
||||||
return "[" + strings.Join(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
6
src/reflect/internal/example1/example.go
Normal file
6
src/reflect/internal/example1/example.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package example1
|
||||||
|
|
||||||
|
type MyStruct struct {
|
||||||
|
MyStructs []MyStruct
|
||||||
|
MyStruct *MyStruct
|
||||||
|
}
|
||||||
6
src/reflect/internal/example2/example.go
Normal file
6
src/reflect/internal/example2/example.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package example2
|
||||||
|
|
||||||
|
type MyStruct struct {
|
||||||
|
MyStructs []MyStruct
|
||||||
|
MyStruct *MyStruct
|
||||||
|
}
|
||||||
|
|
@ -1599,7 +1599,7 @@ func haveIdenticalType(T, V Type, cmpTags bool) bool {
|
||||||
return T == V
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue