diff options
| author | Daniel Martí <mvdan@mvdan.cc> | 2018-10-28 16:23:00 +0000 |
|---|---|---|
| committer | Daniel Martí <mvdan@mvdan.cc> | 2018-10-28 20:20:00 +0000 |
| commit | 1399b52dc4a3cf5347603bf7011984cf28a34031 (patch) | |
| tree | 8f9b397c37ba1f2e5102d136b0e529ccd7a7e4dc /src/text/template/parse/parse_test.go | |
| parent | 81475ca256df3fdd281c0e656b4e743caacbc4e0 (diff) | |
| download | go-1399b52dc4a3cf5347603bf7011984cf28a34031.tar.xz | |
text/template/parse: error on bad range variables
The package used to accept invalid range pipelines, such as:
{{range $k, .}}
{{range $k, 123 := .}}
This is because the logic that allowed a range pipeline to declare
multiple variables was broken. When encountering a single comma inside a
range pipeline, it would happily continue parsing a second variable,
even if we didn't have a variable token at all.
Then, the loop would immediately break, and we'd parse the pipeline we'd
be ranging over. That is, we'd parse {{range $k, .}} as if it were
{{range $k = .}}.
To fix this, only allow the loop to continue if we know we're going to
parse another variable or a token that would end the pipeline. Also add
a few test cases for these error edge cases.
While at it, make use of T.Run, which was useful in debugging
Tree.pipeline via print statements.
Fixes #28437.
Change-Id: Idc9966bf643f0f3bc1b052620357e5b0aa2022ea
Reviewed-on: https://go-review.googlesource.com/c/145282
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/text/template/parse/parse_test.go')
| -rw-r--r-- | src/text/template/parse/parse_test.go | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go index d03987581c..15cc65670a 100644 --- a/src/text/template/parse/parse_test.go +++ b/src/text/template/parse/parse_test.go @@ -450,18 +450,37 @@ var errorTests = []parseTest{ {"multilinerawstring", "{{ $v := `\n` }} {{", hasError, `multilinerawstring:2: unexpected unclosed action`}, + {"rangeundefvar", + "{{range $k}}{{end}}", + hasError, `undefined variable`}, + {"rangeundefvars", + "{{range $k, $v}}{{end}}", + hasError, `undefined variable`}, + {"rangemissingvalue1", + "{{range $k,}}{{end}}", + hasError, `missing value for range`}, + {"rangemissingvalue2", + "{{range $k, $v := }}{{end}}", + hasError, `missing value for range`}, + {"rangenotvariable1", + "{{range $k, .}}{{end}}", + hasError, `range can only initialize variables`}, + {"rangenotvariable2", + "{{range $k, 123 := .}}{{end}}", + hasError, `range can only initialize variables`}, } func TestErrors(t *testing.T) { for _, test := range errorTests { - _, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree)) - if err == nil { - t.Errorf("%q: expected error", test.name) - continue - } - if !strings.Contains(err.Error(), test.result) { - t.Errorf("%q: error %q does not contain %q", test.name, err, test.result) - } + t.Run(test.name, func(t *testing.T) { + _, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree)) + if err == nil { + t.Fatalf("expected error %q, got nil", test.result) + } + if !strings.Contains(err.Error(), test.result) { + t.Fatalf("error %q does not contain %q", err, test.result) + } + }) } } |
