Skip to content

Commit

Permalink
html/template: fix multiple Clones of redefined template
Browse files Browse the repository at this point in the history
This change redoes the fix for #16101 (CL 31092) in a different way by
making t.Clone return the template associated with the t.Name() while
allowing for the case that a template of the same name is define-d.

Fixes #17735.

Change-Id: I1e69672390a4c81aa611046a209008ae4a3bb723
Reviewed-on: https://go-review.googlesource.com/33210
Run-TryBot: Caleb Spare <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Rob Pike <[email protected]>
  • Loading branch information
cespare authored and robpike committed Nov 15, 2016
1 parent 9146100 commit 1e91731
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
21 changes: 21 additions & 0 deletions src/html/template/clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package template
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"sync"
"testing"
Expand Down Expand Up @@ -241,3 +242,23 @@ func TestCloneGrowth(t *testing.T) {
t.Fatalf("too many templates: %v", len(tmpl.DefinedTemplates()))
}
}

// https://golang.org/issue/17735
func TestCloneRedefinedName(t *testing.T) {
const base = `
{{ define "a" -}}<title>{{ template "b" . -}}</title>{{ end -}}
{{ define "b" }}{{ end -}}
`
const page = `{{ template "a" . }}`

t1 := Must(New("a").Parse(base))

for i := 0; i < 2; i++ {
t2 := Must(t1.Clone())
t2 = Must(t2.New(fmt.Sprintf("%d", i)).Parse(page))
err := t2.Execute(ioutil.Discard, nil)
if err != nil {
t.Fatal(err)
}
}
}
6 changes: 2 additions & 4 deletions src/html/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,6 @@ func (t *Template) Clone() (*Template, error) {
ret.set[ret.Name()] = ret
for _, x := range textClone.Templates() {
name := x.Name()
if name == ret.Name() {
continue
}
src := t.set[name]
if src == nil || src.escapeErr != nil {
return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
Expand All @@ -274,7 +271,8 @@ func (t *Template) Clone() (*Template, error) {
ret.nameSpace,
}
}
return ret, nil
// Return the template associated with the name of this template.
return ret.set[ret.Name()], nil
}

// New allocates a new HTML template with the given name.
Expand Down

0 comments on commit 1e91731

Please sign in to comment.