mirror of
https://github.com/golang/go
synced 2024-11-12 09:50:21 -07:00
exp/template: fix endless loop
No progress was made in indirect() if the reflect.Value was an non-nil and non-empty interface. R=r, r CC=golang-dev https://golang.org/cl/4810060
This commit is contained in:
parent
bf184398f6
commit
7162f39fc3
@ -585,12 +585,12 @@ func (s *state) evalEmptyInterface(dot reflect.Value, n node) reflect.Value {
|
||||
// We indirect through pointers and empty interfaces (only) because
|
||||
// non-empty interfaces have methods we might need.
|
||||
func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
|
||||
for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
|
||||
for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
|
||||
if v.IsNil() {
|
||||
return v, true
|
||||
}
|
||||
if v.Kind() == reflect.Ptr || v.NumMethod() == 0 {
|
||||
v = v.Elem()
|
||||
if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return v, false
|
||||
|
@ -75,6 +75,13 @@ var tVal = &T{
|
||||
Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X
|
||||
}
|
||||
|
||||
// A non-empty interface.
|
||||
type I interface {
|
||||
Method0() string
|
||||
}
|
||||
|
||||
var iVal I = tVal
|
||||
|
||||
// Helpers for creation.
|
||||
func newInt(n int) *int {
|
||||
p := new(int)
|
||||
@ -344,6 +351,9 @@ var execTests = []execTest{
|
||||
// Fixed bugs.
|
||||
// Must separate dot and receiver; otherwise args are evaluated with dot set to variable.
|
||||
{"bug0", "{{range .MSIone}}{{if $.Method1 .}}X{{end}}{{end}}", "X", tVal, true},
|
||||
// Do not loop endlessly in indirect for non-empty interfaces.
|
||||
// The bug appears with *interface only; this is supposed to fail (cannot invoke Method0), but terminate.
|
||||
{"bug1", "{{.Method0}}", "", &iVal, false},
|
||||
}
|
||||
|
||||
func zeroArgs() string {
|
||||
|
Loading…
Reference in New Issue
Block a user