aboutsummaryrefslogtreecommitdiff
path: root/src/text
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-03-10 21:43:45 +0000
committerRob Pike <r@golang.org>2019-05-14 00:50:42 +0000
commit45d74aad539c645d4e50a405f55ca46811dd70d6 (patch)
treed761cdcf1beba9fce676e192ad745d660dffd05a /src/text
parenteebb9db0ef1a4cad2f5dd7e8b90f699a1d50bf91 (diff)
downloadgo-45d74aad539c645d4e50a405f55ca46811dd70d6.tar.gz
go-45d74aad539c645d4e50a405f55ca46811dd70d6.zip
text/template: fix truth handling of typed interface nils in if and with
Before this commit, the two logically equivalent conditionals below would produce different output: {{ if not .NonEmptyInterfaceTypedNil }}OK{{ else }}{{ end }} {{ if .NonEmptyInterfaceTypedNil }}{{ else }}OK{{ end }} The functions `not`, `or`, and `and` all use the same `truth` function, which unwraps any concrete interface value before passing it to `isTrue`. `if` and `with` also use `isTrue` to establish truth, but was missing the interface indirect call. Fixes #30501 Change-Id: I9c49eed41e737d8f162e39bef1c3b82fd5518fed GitHub-Last-Rev: 95fc2c82f26d24a457de4deaa7e5756718fbf07c GitHub-Pull-Request: golang/go#30534 Reviewed-on: https://go-review.googlesource.com/c/go/+/164958 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/text')
-rw-r--r--src/text/template/exec.go2
-rw-r--r--src/text/template/exec_test.go2
2 files changed, 3 insertions, 1 deletions
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index 0e2ab0e211..4db63bfa09 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -285,7 +285,7 @@ func (s *state) walk(dot reflect.Value, node parse.Node) {
func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) {
defer s.pop(s.mark())
val := s.evalPipeline(dot, pipe)
- truth, ok := isTrue(val)
+ truth, ok := isTrue(indirectInterface(val))
if !ok {
s.errorf("if/with can't use %v", val)
}
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index a95631718c..c45df89d59 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -413,6 +413,7 @@ var execTests = []execTest{
{"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
{"if false", "{{if false}}TRUE{{else}}FALSE{{end}}", "FALSE", tVal, true},
{"if nil", "{{if nil}}TRUE{{end}}", "", tVal, false},
+ {"if on typed nil interface value", "{{if .NonEmptyInterfaceTypedNil}}TRUE{{ end }}", "", tVal, true},
{"if 1", "{{if 1}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
{"if 0", "{{if 0}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
{"if 1.5", "{{if 1.5}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
@@ -515,6 +516,7 @@ var execTests = []execTest{
{"with $x int", "{{with $x := .I}}{{$x}}{{end}}", "17", tVal, true},
{"with $x struct.U.V", "{{with $x := $}}{{$x.U.V}}{{end}}", "v", tVal, true},
{"with variable and action", "{{with $x := $}}{{$y := $.U.V}}{{$y}}{{end}}", "v", tVal, true},
+ {"with on typed nil interface value", "{{with .NonEmptyInterfaceTypedNil}}TRUE{{ end }}", "", tVal, true},
// Range.
{"range []int", "{{range .SI}}-{{.}}-{{end}}", "-3--4--5-", tVal, true},