Skip to content

Commit 1e91731

Browse files
cesparerobpike
authored andcommitted
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
1 parent 9146100 commit 1e91731

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/html/template/clone_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package template
77
import (
88
"bytes"
99
"errors"
10+
"fmt"
1011
"io/ioutil"
1112
"sync"
1213
"testing"
@@ -241,3 +242,23 @@ func TestCloneGrowth(t *testing.T) {
241242
t.Fatalf("too many templates: %v", len(tmpl.DefinedTemplates()))
242243
}
243244
}
245+
246+
// https://golang.org/issue/17735
247+
func TestCloneRedefinedName(t *testing.T) {
248+
const base = `
249+
{{ define "a" -}}<title>{{ template "b" . -}}</title>{{ end -}}
250+
{{ define "b" }}{{ end -}}
251+
`
252+
const page = `{{ template "a" . }}`
253+
254+
t1 := Must(New("a").Parse(base))
255+
256+
for i := 0; i < 2; i++ {
257+
t2 := Must(t1.Clone())
258+
t2 = Must(t2.New(fmt.Sprintf("%d", i)).Parse(page))
259+
err := t2.Execute(ioutil.Discard, nil)
260+
if err != nil {
261+
t.Fatal(err)
262+
}
263+
}
264+
}

src/html/template/template.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,6 @@ func (t *Template) Clone() (*Template, error) {
259259
ret.set[ret.Name()] = ret
260260
for _, x := range textClone.Templates() {
261261
name := x.Name()
262-
if name == ret.Name() {
263-
continue
264-
}
265262
src := t.set[name]
266263
if src == nil || src.escapeErr != nil {
267264
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) {
274271
ret.nameSpace,
275272
}
276273
}
277-
return ret, nil
274+
// Return the template associated with the name of this template.
275+
return ret.set[ret.Name()], nil
278276
}
279277

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

0 commit comments

Comments
 (0)