Skip to content

Commit

Permalink
text/template: undo reflect.Value wrapping for short-circuit and/or
Browse files Browse the repository at this point in the history
For #31103

Change-Id: I9c0aa64f95f564de31a4c178e3930584d41316bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/353610
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
  • Loading branch information
ianlancetaylor committed Oct 1, 2021
1 parent 0d65c27 commit c129af9
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/text/template/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,20 +714,27 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
s.errorf("can't call method/function %q with %d results", name, typ.NumOut())
}

unwrap := func(v reflect.Value) reflect.Value {
if v.Type() == reflectValueType {
v = v.Interface().(reflect.Value)
}
return v
}

// Special case for builtin and/or, which short-circuit.
if isBuiltin && (name == "and" || name == "or") {
argType := typ.In(0)
var v reflect.Value
for _, arg := range args {
v = s.evalArg(dot, argType, arg).Interface().(reflect.Value)
if truth(v) == (name == "or") {
return v
return unwrap(v)
}
}
if final != missingVal {
v = s.validateType(final, argType)
}
return v
return unwrap(v)
}

// Build the arg list.
Expand Down Expand Up @@ -767,10 +774,7 @@ func (s *state) evalCall(dot, fun reflect.Value, isBuiltin bool, node parse.Node
s.at(node)
s.errorf("error calling %s: %w", name, err)
}
if v.Type() == reflectValueType {
v = v.Interface().(reflect.Value)
}
return v
return unwrap(v)
}

// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
Expand Down
1 change: 1 addition & 0 deletions src/text/template/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ var execTests = []execTest{
{"or pipe-false", "{{0 | or 0}}", "0", 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},

// Indexing.
{"slice[0]", "{{index .SI 0}}", "3", tVal, true},
Expand Down

0 comments on commit c129af9

Please sign in to comment.