summaryrefslogtreecommitdiffstats
path: root/tpl/internal/go_templates/texttemplate/parse
diff options
context:
space:
mode:
Diffstat (limited to 'tpl/internal/go_templates/texttemplate/parse')
-rw-r--r--tpl/internal/go_templates/texttemplate/parse/lex.go2
-rw-r--r--tpl/internal/go_templates/texttemplate/parse/parse.go10
-rw-r--r--tpl/internal/go_templates/texttemplate/parse/parse_test.go30
3 files changed, 36 insertions, 6 deletions
diff --git a/tpl/internal/go_templates/texttemplate/parse/lex.go b/tpl/internal/go_templates/texttemplate/parse/lex.go
index 3e60a1ece..70fc86b63 100644
--- a/tpl/internal/go_templates/texttemplate/parse/lex.go
+++ b/tpl/internal/go_templates/texttemplate/parse/lex.go
@@ -520,7 +520,7 @@ func lexVariable(l *lexer) stateFn {
return lexFieldOrVariable(l, itemVariable)
}
-// lexVariable scans a field or variable: [.$]Alphanumeric.
+// lexFieldOrVariable scans a field or variable: [.$]Alphanumeric.
// The . or $ has been scanned.
func lexFieldOrVariable(l *lexer, typ itemType) stateFn {
if l.atTerminator() { // Nothing interesting follows -> "." or "$".
diff --git a/tpl/internal/go_templates/texttemplate/parse/parse.go b/tpl/internal/go_templates/texttemplate/parse/parse.go
index 87b7618f7..d43d5334b 100644
--- a/tpl/internal/go_templates/texttemplate/parse/parse.go
+++ b/tpl/internal/go_templates/texttemplate/parse/parse.go
@@ -223,6 +223,11 @@ func (t *Tree) startParse(funcs []map[string]any, lex *lexer, treeSet map[string
t.vars = []string{"$"}
t.funcs = funcs
t.treeSet = treeSet
+ lex.options = lexOptions{
+ emitComment: t.Mode&ParseComments != 0,
+ breakOK: !t.hasFunction("break"),
+ continueOK: !t.hasFunction("continue"),
+ }
}
// stopParse terminates parsing.
@@ -241,11 +246,6 @@ func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tre
defer t.recover(&err)
t.ParseName = t.Name
lexer := lex(t.Name, text, leftDelim, rightDelim)
- lexer.options = lexOptions{
- emitComment: t.Mode&ParseComments != 0,
- breakOK: !t.hasFunction("break"),
- continueOK: !t.hasFunction("continue"),
- }
t.startParse(funcs, lexer, treeSet)
t.text = text
t.parse()
diff --git a/tpl/internal/go_templates/texttemplate/parse/parse_test.go b/tpl/internal/go_templates/texttemplate/parse/parse_test.go
index 6ab48b3f7..080eea2f9 100644
--- a/tpl/internal/go_templates/texttemplate/parse/parse_test.go
+++ b/tpl/internal/go_templates/texttemplate/parse/parse_test.go
@@ -394,6 +394,36 @@ func TestParseWithComments(t *testing.T) {
}
}
+func TestKeywordsAndFuncs(t *testing.T) {
+ // Check collisions between functions and new keywords like 'break'. When a
+ // break function is provided, the parser should treat 'break' as a function,
+ // not a keyword.
+ textFormat = "%q"
+ defer func() { textFormat = "%s" }()
+
+ inp := `{{range .X}}{{break 20}}{{end}}`
+ {
+ // 'break' is a defined function, don't treat it as a keyword: it should
+ // accept an argument successfully.
+ var funcsWithKeywordFunc = map[string]any{
+ "break": func(in any) any { return in },
+ }
+ tmpl, err := New("").Parse(inp, "", "", make(map[string]*Tree), funcsWithKeywordFunc)
+ if err != nil || tmpl == nil {
+ t.Errorf("with break func: unexpected error: %v", err)
+ }
+ }
+
+ {
+ // No function called 'break'; treat it as a keyword. Results in a parse
+ // error.
+ tmpl, err := New("").Parse(inp, "", "", make(map[string]*Tree), make(map[string]any))
+ if err == nil || tmpl != nil {
+ t.Errorf("without break func: expected error; got none")
+ }
+ }
+}
+
func TestSkipFuncCheck(t *testing.T) {
oldTextFormat := textFormat
textFormat = "%q"