mirror of
https://github.com/golang/go
synced 2024-11-19 21:34:45 -07:00
text/template: catch unexported fields during parse
It's a common error to reference unexported field names in templates, especially for newcomers. This catches the error at parse time rather than execute time so the rare few who check errors will notice right away. These were always an error, so the net behavior is unchanged. Should break no existing code, just identify the error earlier. R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/6009048
This commit is contained in:
parent
e6c5e2a363
commit
2d0d3d8f9e
@ -348,7 +348,7 @@ Loop:
|
||||
l.backup()
|
||||
word := l.input[l.start:l.pos]
|
||||
if !l.atTerminator() {
|
||||
return l.errorf("unexpected character %+U", r)
|
||||
return l.errorf("bad character %+U", r)
|
||||
}
|
||||
switch {
|
||||
case key[word] > itemKeyword:
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Tree is the representation of a single parsed template.
|
||||
@ -473,6 +474,9 @@ Loop:
|
||||
case itemVariable:
|
||||
cmd.append(t.useVar(token.val))
|
||||
case itemField:
|
||||
if !isExported(token.val) {
|
||||
t.errorf("field %q not exported; cannot be evaluated", token.val)
|
||||
}
|
||||
cmd.append(newField(token.val))
|
||||
case itemBool:
|
||||
cmd.append(newBool(token.val == "true"))
|
||||
@ -498,6 +502,12 @@ Loop:
|
||||
return cmd
|
||||
}
|
||||
|
||||
// isExported reports whether the field name (which starts with a period) can be accessed.
|
||||
func isExported(fieldName string) bool {
|
||||
r, _ := utf8.DecodeRuneInString(fieldName[1:]) // drop the period
|
||||
return unicode.IsUpper(r)
|
||||
}
|
||||
|
||||
// hasFunction reports if a function name exists in the Tree's maps.
|
||||
func (t *Tree) hasFunction(name string) bool {
|
||||
for _, funcMap := range t.funcs {
|
||||
|
@ -230,6 +230,7 @@ var parseTests = []parseTest{
|
||||
{"invalid punctuation", "{{printf 3, 4}}", hasError, ""},
|
||||
{"multidecl outside range", "{{with $v, $u := 3}}{{end}}", hasError, ""},
|
||||
{"too many decls in range", "{{range $u, $v, $w := 3}}{{end}}", hasError, ""},
|
||||
{"unexported field", "{{.local}}", hasError, ""},
|
||||
// Equals (and other chars) do not assignments make (yet).
|
||||
{"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
|
||||
{"bug0b", "{{$x = 1}}{{$x}}", hasError, ""},
|
||||
|
Loading…
Reference in New Issue
Block a user