html/template: fix nil pointer bug

Fixes #3272.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5819046
This commit is contained in:
Rob Pike 2012-03-14 15:08:54 +11:00
parent 9eeb90945e
commit 214a1ca3c5
2 changed files with 18 additions and 3 deletions

View File

@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"strings" "strings"
"testing" "testing"
"text/template" "text/template"
@ -1637,6 +1638,14 @@ func TestIndirectPrint(t *testing.T) {
} }
} }
// This is a test for issue 3272.
func TestEmptyTemplate(t *testing.T) {
page := Must(New("page").ParseFiles(os.DevNull))
if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil {
t.Fatal("expected error")
}
}
func BenchmarkEscapedExecute(b *testing.B) { func BenchmarkEscapedExecute(b *testing.B) {
tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`)) tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
var buf bytes.Buffer var buf bytes.Buffer

View File

@ -64,7 +64,13 @@ func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err err
t.nameSpace.mu.Lock() t.nameSpace.mu.Lock()
defer t.nameSpace.mu.Unlock() defer t.nameSpace.mu.Unlock()
tmpl = t.set[name] tmpl = t.set[name]
if (tmpl == nil) != (t.text.Lookup(name) == nil) { if tmpl == nil {
return nil, fmt.Errorf("html/template: %q is undefined", name)
}
if tmpl.text.Tree == nil || tmpl.text.Root == nil {
return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
}
if t.text.Lookup(name) == nil {
panic("html/template internal error: template escaping out of sync") panic("html/template internal error: template escaping out of sync")
} }
if tmpl != nil && !tmpl.escaped { if tmpl != nil && !tmpl.escaped {
@ -276,7 +282,7 @@ func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
func parseFiles(t *Template, filenames ...string) (*Template, error) { func parseFiles(t *Template, filenames ...string) (*Template, error) {
if len(filenames) == 0 { if len(filenames) == 0 {
// Not really a problem, but be consistent. // Not really a problem, but be consistent.
return nil, fmt.Errorf("template: no files named in call to ParseFiles") return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
} }
for _, filename := range filenames { for _, filename := range filenames {
b, err := ioutil.ReadFile(filename) b, err := ioutil.ReadFile(filename)
@ -333,7 +339,7 @@ func parseGlob(t *Template, pattern string) (*Template, error) {
return nil, err return nil, err
} }
if len(filenames) == 0 { if len(filenames) == 0 {
return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
} }
return parseFiles(t, filenames...) return parseFiles(t, filenames...)
} }