]> Cypherpunks repositories - gostls13.git/commitdiff
exp/template: don't panic on range of nil interface
authorGustavo Niemeyer <gustavo@niemeyer.net>
Mon, 15 Aug 2011 03:22:28 +0000 (00:22 -0300)
committerGustavo Niemeyer <gustavo@niemeyer.net>
Mon, 15 Aug 2011 03:22:28 +0000 (00:22 -0300)
This avoids a non-obvious panic when range is used on a
nil interface, and fixes it by behaving as if the range
was empty.

The new behavior is equivalent to the outcome of iterating
on a nil map or slice, and is useful because it allows
generic structures such as used in json (map[string]interface{})
to behave correctly if a key generally set to a list or map
isn't present.

R=golang-dev, r, gustavo
CC=golang-dev
https://golang.org/cl/4876046

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

index ff4e3876afc1387a235e82ad4073207c608c0263..06e5d2b3b89aadf3cacd61f4b17d95f6d0da3137 100644 (file)
@@ -233,8 +233,10 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
                        s.pop(mark)
                }
                return
+       case reflect.Invalid:
+               break // An invalid value is likely a nil map, etc. and acts like an empty map.
        default:
-               s.errorf("range can't iterate over value of type %T", val.Interface())
+               s.errorf("range can't iterate over %v", val)
        }
        if r.ElseList != nil {
                s.walk(dot, r.ElseList)
index a8ef64d2e0f63aeafbee1d57b0380dfc83877702..8a610da63bd8b87121eb04b92a885cea40403bef 100644 (file)
@@ -372,6 +372,7 @@ var execTests = []execTest{
        {"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true},
        {"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
        {"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
+       {"range empty nil", "{{range .Empty0}}-{{.}}-{{end}}", "", tVal, true},
        {"range $x SI", "{{range $x := .SI}}<{{$x}}>{{end}}", "<3><4><5>", tVal, true},
        {"range $x $y SI", "{{range $x, $y := .SI}}<{{$x}}={{$y}}>{{end}}", "<0=3><1=4><2=5>", tVal, true},
        {"range $x MSIone", "{{range $x := .MSIone}}<{{$x}}>{{end}}", "<1>", tVal, true},