Commit 53d9b6fc authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder Committed by Rob Pike

html/template: handle nils during indirection

Fixes #5982.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/12387043
parent 67f2ca35
......@@ -74,6 +74,9 @@ const (
// indirect returns the value, after dereferencing as many times
// as necessary to reach the base type (or nil).
func indirect(a interface{}) interface{} {
if a == nil {
return nil
}
if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
// Avoid creating a reflect.Value if it's not a pointer.
return a
......@@ -94,6 +97,9 @@ var (
// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
// or error,
func indirectToStringerOrError(a interface{}) interface{} {
if a == nil {
return nil
}
v := reflect.ValueOf(a)
for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
v = v.Elem()
......
......@@ -259,3 +259,28 @@ func TestStringer(t *testing.T) {
t.Errorf("expected %q got %q", expect, b.String())
}
}
// https://code.google.com/p/go/issues/detail?id=5982
func TestEscapingNilNonemptyInterfaces(t *testing.T) {
tmpl := Must(New("x").Parse("{{.E}}"))
defer func() {
if r := recover(); r != nil {
t.Errorf("panic during template execution: %v", r)
}
}()
got := new(bytes.Buffer)
testData := struct{ E error }{} // any non-empty interface here will do; error is just ready at hand
tmpl.Execute(got, testData)
// Use this data instead of just hard-coding "<nil>" to avoid
// dependencies on the html escaper and the behavior of fmt w.r.t. nil.
want := new(bytes.Buffer)
data := struct{ E string }{E: fmt.Sprint(nil)}
tmpl.Execute(want, data)
if !bytes.Equal(want.Bytes(), got.Bytes()) {
t.Errorf("expected %q got %q", string(want.Bytes()), string(got.Bytes()))
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment