]> Cypherpunks repositories - gostls13.git/commitdiff
html/template: fix multiple Clones of redefined template
authorCaleb Spare <cespare@gmail.com>
Mon, 14 Nov 2016 02:06:16 +0000 (18:06 -0800)
committerRob Pike <r@golang.org>
Tue, 15 Nov 2016 04:30:20 +0000 (04:30 +0000)
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 <cespare@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
src/html/template/clone_test.go
src/html/template/template.go

index bbe44f98dd16ca51fc225b734349f065c8a04ae8..b500715ac6efa7db239d74cd1689b6c43bce519a 100644 (file)
@@ -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" -}}<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)
+               }
+       }
+}
index a98d151c507e6e912225ce7e1d6ae1688fa51093..b313a6b104aa160a745a970d0d803b5ffbf9b955 100644 (file)
@@ -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.