summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2015-03-20 10:47:52 -0700
committerRob Pike <r@golang.org>2015-03-20 19:57:45 +0000
commit11dba2ec2d8fcedc1da0103925c254586ef51120 (patch)
tree1d66a39e3293847dae8d3c52d7237fce58338318 /src
parent3f12d271335abc9d49d419247528cf286a04f9a6 (diff)
downloadgo-git-11dba2ec2d8fcedc1da0103925c254586ef51120.tar.gz
html/template: fix crash when escaping incomplete template
text/template turned this into an error but html/template crashed. Refactor text/template.Execute to export a new function, text/template.DefinedTemplates, so html/template can get the same helpful error message in this case, and invoke it when there is no definition for a template being escaped. Fixes #10204. Change-Id: I1d04e9e7ebca829bc08509caeb65e75da969711f Reviewed-on: https://go-review.googlesource.com/7855 Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/html/template/escape_test.go15
-rw-r--r--src/html/template/template.go3
-rw-r--r--src/text/template/exec.go39
3 files changed, 43 insertions, 14 deletions
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index ef7b877484..9c9502a617 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -1686,6 +1686,21 @@ func TestPipeToMethodIsEscaped(t *testing.T) {
}
}
+// Unlike text/template, html/template crashed if given an incomplete
+// template, that is, a template that had been named but not given any content.
+// This is issue #10204.
+func TestErrorOnUndefined(t *testing.T) {
+ tmpl := New("undefined")
+
+ err := tmpl.Execute(nil, nil)
+ if err == nil {
+ t.Error("expected error")
+ }
+ if !strings.Contains(err.Error(), "incomplete") {
+ t.Errorf("expected error about incomplete template; got %s", err)
+ }
+}
+
func BenchmarkEscapedExecute(b *testing.B) {
tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
var buf bytes.Buffer
diff --git a/src/html/template/template.go b/src/html/template/template.go
index ce6170105c..64c0041c9c 100644
--- a/src/html/template/template.go
+++ b/src/html/template/template.go
@@ -56,6 +56,9 @@ func (t *Template) escape() error {
t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock()
if t.escapeErr == nil {
+ if t.Tree == nil {
+ return fmt.Errorf("template: %q is an incomplete or empty template%s", t.Name(), t.text.DefinedTemplates())
+ }
if err := escapeTemplate(t, t.text.Root, t.Name()); err != nil {
return err
}
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index faf31e3ede..613a778188 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -136,24 +136,35 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
}
t.init()
if t.Tree == nil || t.Root == nil {
- var b bytes.Buffer
- for name, tmpl := range t.tmpl {
- if tmpl.Tree == nil || tmpl.Root == nil {
- continue
- }
- if b.Len() > 0 {
- b.WriteString(", ")
- }
- fmt.Fprintf(&b, "%q", name)
+ state.errorf("%q is an incomplete or empty template%s", t.Name(), t.DefinedTemplates())
+ }
+ state.walk(value, t.Root)
+ return
+}
+
+// DefinedTemplates returns a string listing the defined templates,
+// prefixed by the string "defined templates are: ". If there are none,
+// it returns the empty string. For generating an error message here
+// and in html/template.
+func (t *Template) DefinedTemplates() string {
+ if t.common == nil {
+ return ""
+ }
+ var b bytes.Buffer
+ for name, tmpl := range t.tmpl {
+ if tmpl.Tree == nil || tmpl.Root == nil {
+ continue
}
- var s string
if b.Len() > 0 {
- s = "; defined templates are: " + b.String()
+ b.WriteString(", ")
}
- state.errorf("%q is an incomplete or empty template%s", t.Name(), s)
+ fmt.Fprintf(&b, "%q", name)
}
- state.walk(value, t.Root)
- return
+ var s string
+ if b.Len() > 0 {
+ s = "; defined templates are: " + b.String()
+ }
+ return s
}
// Walk functions step through the major pieces of the template structure,