mirror of
https://github.com/golang/go
synced 2024-11-23 18:00:06 -07:00
text/template: check for literals in chain of terms
The current parser ignores obvious errors such as: {{0.1.E}} {{true.any}} {{"hello".wrong}} {{nil.E}} The common problem is that a chain is built from a literal value. It then panics at execution time. Furthermore, a double dot triggers the same behavior: {{..E}} Addresses a TODO left in Tree.operand to catch these errors at parsing time. Note that identifiers can include a '.', and pipelines could return an object which a field can be derived from (like a variable), so they are excluded from the check. Fixes #10615 Change-Id: I903706d1c17861b5a8354632c291e73c9c0bc4e1 Reviewed-on: https://go-review.googlesource.com/9621 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
172f27652e
commit
76ace947ae
@ -527,8 +527,10 @@ var execTests = []execTest{
|
||||
{"bug12XE", "{{printf `%T` 0XEE}}", "int", T{}, true},
|
||||
// Chained nodes did not work as arguments. Issue 8473.
|
||||
{"bug13", "{{print (.Copy).I}}", "17", tVal, true},
|
||||
// Didn't protect against explicit nil in field chains.
|
||||
{"bug14", "{{nil.True}}", "", tVal, false},
|
||||
// Didn't protect against nil or literal values in field chains.
|
||||
{"bug14a", "{{(nil).True}}", "", tVal, false},
|
||||
{"bug14b", "{{$x := nil}}{{$x.anything}}", "", tVal, false},
|
||||
{"bug14c", `{{$x := (1.0)}}{{$y := ("hello")}}{{$x.anything}}{{$y.true}}`, "", tVal, false},
|
||||
}
|
||||
|
||||
func zeroArgs() string {
|
||||
|
@ -554,7 +554,7 @@ func (t *Tree) command() *CommandNode {
|
||||
t.backup()
|
||||
case itemPipe:
|
||||
default:
|
||||
t.errorf("unexpected %s in operand; missing space?", token)
|
||||
t.errorf("unexpected %s in operand", token)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -582,12 +582,15 @@ func (t *Tree) operand() Node {
|
||||
// Compatibility with original API: If the term is of type NodeField
|
||||
// or NodeVariable, just put more fields on the original.
|
||||
// Otherwise, keep the Chain node.
|
||||
// TODO: Switch to Chains always when we can.
|
||||
// Obvious parsing errors involving literal values are detected here.
|
||||
// More complex error cases will have to be handled at execution time.
|
||||
switch node.Type() {
|
||||
case NodeField:
|
||||
node = t.newField(chain.Position(), chain.String())
|
||||
case NodeVariable:
|
||||
node = t.newVariable(chain.Position(), chain.String())
|
||||
case NodeBool, NodeString, NodeNumber, NodeNil, NodeDot:
|
||||
t.errorf("unexpected . after term %q", node.String())
|
||||
default:
|
||||
node = chain
|
||||
}
|
||||
|
@ -260,6 +260,14 @@ var parseTests = []parseTest{
|
||||
{"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""}, // ! is just illegal here.
|
||||
{"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""}, // $x+2 should not parse as ($x) (+2).
|
||||
{"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
|
||||
// dot following a literal value
|
||||
{"dot after integer", "{{1.E}}", hasError, ""},
|
||||
{"dot after float", "{{0.1.E}}", hasError, ""},
|
||||
{"dot after boolean", "{{true.E}}", hasError, ""},
|
||||
{"dot after char", "{{'a'.any}}", hasError, ""},
|
||||
{"dot after string", `{{"hello".guys}}`, hasError, ""},
|
||||
{"dot after dot", "{{..E}}", hasError, ""},
|
||||
{"dot after nil", "{{nil.E}}", hasError, ""},
|
||||
}
|
||||
|
||||
var builtins = map[string]interface{}{
|
||||
@ -378,7 +386,7 @@ var errorTests = []parseTest{
|
||||
hasError, `unexpected ")"`},
|
||||
{"space",
|
||||
"{{`x`3}}",
|
||||
hasError, `missing space?`},
|
||||
hasError, `in operand`},
|
||||
{"idchar",
|
||||
"{{a#}}",
|
||||
hasError, `'#'`},
|
||||
@ -410,6 +418,9 @@ var errorTests = []parseTest{
|
||||
{"undefvar",
|
||||
"{{$a}}",
|
||||
hasError, `undefined variable`},
|
||||
{"wrongdot",
|
||||
"{{true.any}}",
|
||||
hasError, `unexpected . after term`},
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user