]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: don't panic when function call evaluates a nil pointer
authorRob Pike <r@golang.org>
Sat, 15 Feb 2014 00:26:47 +0000 (16:26 -0800)
committerRob Pike <r@golang.org>
Sat, 15 Feb 2014 00:26:47 +0000 (16:26 -0800)
Catch the error instead and return it to the user. Before this fix,
the template package panicked. Now you get:
        template: bug11:1:14: executing "bug11" at <.PS>: dereference of nil pointer of type *string
Extended example at http://play.golang.org/p/uP6pCW3qKT

Fixes #7333.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/64150043

src/pkg/text/template/exec.go
src/pkg/text/template/exec_test.go

index 43b0b266eca77c742bded27274995308223e7b6e..6de37a19963f35a3c345b549f979e34babc42d36 100644 (file)
@@ -594,6 +594,9 @@ func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Valu
                switch {
                case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
                        value = value.Elem()
+                       if !value.IsValid() {
+                               s.errorf("dereference of nil pointer of type %s", typ)
+                       }
                case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
                        value = value.Addr()
                default:
index f60702de8f14aea8041debc506e08f8b75f10eab..868f2cb94c392d649c6ab907e3d9c28cad8e646c 100644 (file)
@@ -512,6 +512,8 @@ var execTests = []execTest{
        {"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
        // Field chain starting with function did not work.
        {"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
+       // Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333.
+       {"bug11", "{{valueString .PS}}", "", T{}, false},
 }
 
 func zeroArgs() string {
@@ -546,6 +548,11 @@ func vfunc(V, *V) string {
        return "vfunc"
 }
 
+// valueString takes a string, not a pointer.
+func valueString(v string) string {
+       return "value is ignored"
+}
+
 func add(args ...int) int {
        sum := 0
        for _, x := range args {
@@ -580,17 +587,18 @@ func mapOfThree() interface{} {
 func testExecute(execTests []execTest, template *Template, t *testing.T) {
        b := new(bytes.Buffer)
        funcs := FuncMap{
-               "add":        add,
-               "count":      count,
-               "dddArg":     dddArg,
-               "echo":       echo,
-               "makemap":    makemap,
-               "mapOfThree": mapOfThree,
-               "oneArg":     oneArg,
-               "stringer":   stringer,
-               "typeOf":     typeOf,
-               "vfunc":      vfunc,
-               "zeroArgs":   zeroArgs,
+               "add":         add,
+               "count":       count,
+               "dddArg":      dddArg,
+               "echo":        echo,
+               "makemap":     makemap,
+               "mapOfThree":  mapOfThree,
+               "oneArg":      oneArg,
+               "stringer":    stringer,
+               "typeOf":      typeOf,
+               "valueString": valueString,
+               "vfunc":       vfunc,
+               "zeroArgs":    zeroArgs,
        }
        for _, test := range execTests {
                var tmpl *Template