]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: fix bug in Clone
authorRob Pike <r@golang.org>
Fri, 25 Nov 2011 00:07:19 +0000 (16:07 -0800)
committerRob Pike <r@golang.org>
Fri, 25 Nov 2011 00:07:19 +0000 (16:07 -0800)
Cloned template copied the root template incorrectly.
Add test of self-consistency.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5436063

src/pkg/text/template/multi_test.go
src/pkg/text/template/template.go

index 1f6385da49b775682714ecab23d95dfab375facb..bf4f3078b3c11b4a1a3045f25bd83d4b23f55591 100644 (file)
@@ -230,6 +230,15 @@ func TestClone(t *testing.T) {
        if err != nil {
                t.Fatal(err)
        }
+       // Verify that the clone is self-consistent.
+       for k, v := range clone.tmpl {
+               if k == clone.name && v.tmpl[k] != clone {
+                       t.Error("clone does not contain root")
+               }
+               if v != v.tmpl[v.name] {
+                       t.Errorf("clone does not contain self for %q", k)
+               }
+       }
        // Execute root.
        var b bytes.Buffer
        err = root.ExecuteTemplate(&b, "a", 0)
index 26c0c90307d2eace835963345c51683d120b4bed..27b870715142aaab6ca242b198fbb2d058472580 100644 (file)
@@ -73,12 +73,15 @@ func (t *Template) init() {
 // common templates and use them with variant definitions for other templates by
 // adding the variants after the clone is made.
 func (t *Template) Clone() *Template {
-       nt := t.copy()
+       nt := t.copy(nil)
        nt.init()
+       nt.tmpl[t.name] = nt
        for k, v := range t.tmpl {
+               if k == t.name { // Already installed.
+                       continue
+               }
                // The associated templates share nt's common structure.
-               tmpl := v.copy()
-               tmpl.common = nt.common
+               tmpl := v.copy(nt.common)
                nt.tmpl[k] = tmpl
        }
        for k, v := range t.parseFuncs {
@@ -90,10 +93,11 @@ func (t *Template) Clone() *Template {
        return nt
 }
 
-// copy returns a shallow copy of t, with common set to nil.
-func (t *Template) copy() *Template {
+// copy returns a shallow copy of t, with common set to the argument.
+func (t *Template) copy(c *common) *Template {
        nt := New(t.name)
        nt.Tree = t.Tree
+       nt.common = c
        nt.leftDelim = t.leftDelim
        nt.rightDelim = t.rightDelim
        return nt