diff options
| author | Keith Randall <khr@golang.org> | 2015-05-28 13:49:20 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2015-05-28 13:51:18 -0700 |
| commit | 067e8dfd82163ddcbde248dbe5a1187a417e5d36 (patch) | |
| tree | 7bfb46b901d03498c7739c92bec21d81d3a2c485 /src/text/template | |
| parent | 247786c1745abc0c7185f7c15ca256edf68ed6d6 (diff) | |
| parent | ccc037699e2966b7c79ba84c67471cef5e67a3b8 (diff) | |
| download | go-067e8dfd82163ddcbde248dbe5a1187a417e5d36.tar.xz | |
[dev.ssa] Merge remote-tracking branch 'origin/master' into mergebranch
Semi-regular merge of tip to dev.ssa.
Complicated a bit by the move of cmd/internal/* to cmd/compile/internal/*.
Change-Id: I1c66d3c29bb95cce4a53c5a3476373aa5245303d
Diffstat (limited to 'src/text/template')
| -rw-r--r-- | src/text/template/exec.go | 2 | ||||
| -rw-r--r-- | src/text/template/exec_test.go | 8 | ||||
| -rw-r--r-- | src/text/template/funcs.go | 2 | ||||
| -rw-r--r-- | src/text/template/template.go | 12 |
4 files changed, 21 insertions, 3 deletions
diff --git a/src/text/template/exec.go b/src/text/template/exec.go index e6e1287993..ebafb4b5dc 100644 --- a/src/text/template/exec.go +++ b/src/text/template/exec.go @@ -660,7 +660,7 @@ func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) refle case *parse.PipeNode: return s.validateType(s.evalPipeline(dot, arg), typ) case *parse.IdentifierNode: - return s.evalFunction(dot, arg, arg, nil, zero) + return s.validateType(s.evalFunction(dot, arg, arg, nil, zero), typ) case *parse.ChainNode: return s.validateType(s.evalChainNode(dot, arg, nil, zero), typ) } diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index abce27ff3d..0f1ad62380 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -531,6 +531,8 @@ var execTests = []execTest{ {"bug14a", "{{(nil).True}}", "", tVal, false}, {"bug14b", "{{$x := nil}}{{$x.anything}}", "", tVal, false}, {"bug14c", `{{$x := (1.0)}}{{$y := ("hello")}}{{$x.anything}}{{$y.true}}`, "", tVal, false}, + // Didn't call validateType on function results. Issue 10800. + {"bug15", "{{valueString returnInt}}", "", tVal, false}, } func zeroArgs() string { @@ -570,6 +572,11 @@ func valueString(v string) string { return "value is ignored" } +// returnInt returns an int +func returnInt() int { + return 7 +} + func add(args ...int) int { sum := 0 for _, x := range args { @@ -611,6 +618,7 @@ func testExecute(execTests []execTest, template *Template, t *testing.T) { "makemap": makemap, "mapOfThree": mapOfThree, "oneArg": oneArg, + "returnInt": returnInt, "stringer": stringer, "typeOf": typeOf, "valueString": valueString, diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go index cdd187bda2..ccd0dfc80d 100644 --- a/src/text/template/funcs.go +++ b/src/text/template/funcs.go @@ -92,6 +92,8 @@ func goodFunc(typ reflect.Type) bool { // findFunction looks for a function in the template, and global map. func findFunction(name string, tmpl *Template) (reflect.Value, bool) { if tmpl != nil && tmpl.common != nil { + tmpl.muFuncs.RLock() + defer tmpl.muFuncs.RUnlock() if fn := tmpl.execFuncs[name]; fn.IsValid() { return fn, true } diff --git a/src/text/template/template.go b/src/text/template/template.go index 8611faad9f..a7c5c8cd2c 100644 --- a/src/text/template/template.go +++ b/src/text/template/template.go @@ -7,18 +7,20 @@ package template import ( "fmt" "reflect" + "sync" "text/template/parse" ) // common holds the information shared by related templates. type common struct { - tmpl map[string]*Template + tmpl map[string]*Template + option option // We use two maps, one for parsing and one for execution. // This separation makes the API cleaner since it doesn't // expose reflection to the client. + muFuncs sync.RWMutex // protects parseFuncs and execFuncs parseFuncs FuncMap execFuncs map[string]reflect.Value - option option } // Template is the representation of a parsed template. The *parse.Tree @@ -84,6 +86,8 @@ func (t *Template) Clone() (*Template, error) { tmpl := v.copy(nt.common) nt.tmpl[k] = tmpl } + t.muFuncs.RLock() + defer t.muFuncs.RUnlock() for k, v := range t.parseFuncs { nt.parseFuncs[k] = v } @@ -146,6 +150,8 @@ func (t *Template) Delims(left, right string) *Template { // value is the template, so calls can be chained. func (t *Template) Funcs(funcMap FuncMap) *Template { t.init() + t.muFuncs.Lock() + defer t.muFuncs.Unlock() addValueFuncs(t.execFuncs, funcMap) addFuncs(t.parseFuncs, funcMap) return t @@ -169,7 +175,9 @@ func (t *Template) Lookup(name string) *Template { // can contain text other than space, comments, and template definitions.) func (t *Template) Parse(text string) (*Template, error) { t.init() + t.muFuncs.RLock() trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins) + t.muFuncs.RUnlock() if err != nil { return nil, err } |
