mirror of
https://github.com/golang/go
synced 2024-11-25 17:57:56 -07:00
exp/template: truth for interface values.
Also protect against invalid (zero Value) reflect.Values. R=rsc, gri CC=golang-dev https://golang.org/cl/4810094
This commit is contained in:
parent
8f3c7497ac
commit
39fa2a5bf2
@ -148,7 +148,7 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
|
|||||||
val := s.evalPipeline(dot, pipe)
|
val := s.evalPipeline(dot, pipe)
|
||||||
truth, ok := isTrue(val)
|
truth, ok := isTrue(val)
|
||||||
if !ok {
|
if !ok {
|
||||||
s.errorf("if/with can't use value of type %T", val.Interface())
|
s.errorf("if/with can't use %v", val)
|
||||||
}
|
}
|
||||||
if truth {
|
if truth {
|
||||||
if typ == parse.NodeWith {
|
if typ == parse.NodeWith {
|
||||||
@ -164,6 +164,10 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
|
|||||||
// isTrue returns whether the value is 'true', in the sense of not the zero of its type,
|
// isTrue returns whether the value is 'true', in the sense of not the zero of its type,
|
||||||
// and whether the value has a meaningful truth value.
|
// and whether the value has a meaningful truth value.
|
||||||
func isTrue(val reflect.Value) (truth, ok bool) {
|
func isTrue(val reflect.Value) (truth, ok bool) {
|
||||||
|
if !val.IsValid() {
|
||||||
|
// Something like var x interface{}, never set. It's a form of nil.
|
||||||
|
return false, true
|
||||||
|
}
|
||||||
switch val.Kind() {
|
switch val.Kind() {
|
||||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
truth = val.Len() > 0
|
truth = val.Len() > 0
|
||||||
@ -171,7 +175,7 @@ func isTrue(val reflect.Value) (truth, ok bool) {
|
|||||||
truth = val.Bool()
|
truth = val.Bool()
|
||||||
case reflect.Complex64, reflect.Complex128:
|
case reflect.Complex64, reflect.Complex128:
|
||||||
truth = val.Complex() != 0
|
truth = val.Complex() != 0
|
||||||
case reflect.Chan, reflect.Func, reflect.Ptr:
|
case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
|
||||||
truth = !val.IsNil()
|
truth = !val.IsNil()
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
truth = val.Int() != 0
|
truth = val.Int() != 0
|
||||||
|
@ -366,7 +366,9 @@ var execTests = []execTest{
|
|||||||
// Was taking address of interface field, so method set was empty.
|
// Was taking address of interface field, so method set was empty.
|
||||||
{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
|
{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
|
||||||
// Struct values were not legal in with - mere oversight.
|
// Struct values were not legal in with - mere oversight.
|
||||||
{"bug4", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
|
{"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
|
||||||
|
// Nil interface values in if.
|
||||||
|
{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func zeroArgs() string {
|
func zeroArgs() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user