From: Caleb Spare Date: Mon, 14 Nov 2016 02:06:16 +0000 (-0800) Subject: html/template: fix multiple Clones of redefined template X-Git-Tag: go1.8beta1~159 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1e917312511f6ce54bbdcea8cd0c25e66973d49e;p=gostls13.git html/template: fix multiple Clones of redefined template 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 TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- diff --git a/src/html/template/clone_test.go b/src/html/template/clone_test.go index bbe44f98dd..b500715ac6 100644 --- a/src/html/template/clone_test.go +++ b/src/html/template/clone_test.go @@ -7,6 +7,7 @@ package template import ( "bytes" "errors" + "fmt" "io/ioutil" "sync" "testing" @@ -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" -}}{{ template "b" . -}}{{ 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) + } + } +} diff --git a/src/html/template/template.go b/src/html/template/template.go index a98d151c50..b313a6b104 100644 --- a/src/html/template/template.go +++ b/src/html/template/template.go @@ -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()) @@ -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.