]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: only unwrap final and/or value
authorIan Lance Taylor <iant@golang.org>
Tue, 5 Oct 2021 18:41:40 +0000 (11:41 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 5 Oct 2021 21:22:16 +0000 (21:22 +0000)
In the last CL I missed the fact that except for the final value the
code already unwraps the argument.

For #31103

Change-Id: Ic9099aeb50c6b3322fc14a90ac8026c1d8cb1698
Reviewed-on: https://go-review.googlesource.com/c/go/+/354091
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/text/template/exec.go
src/text/template/exec_test.go

index 9a4c9e29dd3071bdb32315417960c946cbf5a61c..9ae6fdc3ccf035dd4ea6d987607b65d69980f8b7 100644 (file)
@@ -728,13 +728,21 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
                for _, arg := range args {
                        v = s.evalArg(dot, argType, arg).Interface().(reflect.Value)
                        if truth(v) == (name == "or") {
-                               return unwrap(v)
+                               // This value was already unwrapped
+                               // by the .Interface().(reflect.Value).
+                               return v
                        }
                }
                if final != missingVal {
-                       v = s.validateType(final, argType)
+                       // The last argument to and/or is coming from
+                       // the pipeline. We didn't short circuit on an earlier
+                       // argument, so we are going to return this one.
+                       // We don't have to evaluate final, but we do
+                       // have to check its type. Then, since we are
+                       // going to return it, we have to unwrap it.
+                       v = unwrap(s.validateType(final, argType))
                }
-               return unwrap(v)
+               return v
        }
 
        // Build the arg list.
index 1a839a641b05c3ca0999e4931d473b1d45a5ab49..9c0772945e845428df8f7d980cfb2be27d226f99 100644 (file)
@@ -489,6 +489,8 @@ var execTests = []execTest{
        {"and pipe-false", "{{0 | and 1}}", "0", nil, true},
        {"or pipe-true", "{{1 | or 0}}", "1", nil, true},
        {"or pipe-false", "{{0 | or 0}}", "0", nil, true},
+       {"and undef", "{{and 1 .Unknown}}", "<no value>", nil, true},
+       {"or undef", "{{or 0 .Unknown}}", "<no value>", nil, true},
        {"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
        {"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
        {"boolean if pipe", "{{if true | not | and 1}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},