Skip to content

Commit

Permalink
text/template: support delimiters that can be confused with actions
Browse files Browse the repository at this point in the history
In fields that start with the same character as the right delimiter, the
whole delimiter needs to be checked. The first character alone is not
sufficient.

Fixes #52165

Change-Id: I1e4086048417693757f34d0e9ff3bf86aba0d35c
Reviewed-on: https://go-review.googlesource.com/c/go/+/398475
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Rob Pike <[email protected]>
Trust: Ian Lance Taylor <[email protected]>
  • Loading branch information
mprahl authored and ianlancetaylor committed Apr 6, 2022
1 parent 81ae993 commit 9a6acc8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/text/template/parse/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,13 +541,25 @@ func (l *lexer) atTerminator() bool {
case eof, '.', ',', '|', ':', ')', '(':
return true
}
// Does r start the delimiter? This can be ambiguous (with delim=="//", $x/2 will
// succeed but should fail) but only in extremely rare cases caused by willfully
// bad choice of delimiter.
if rd, _ := utf8.DecodeRuneInString(l.rightDelim); rd == r {
return true
// Are we at a right delimiter? TODO: This is harder than it should be
// because lookahead is only one rune.
rightDelim := l.rightDelim
defer func(pos Pos, line int) {
l.pos = pos
l.line = line
}(l.pos, l.line)
for len(rightDelim) > 0 {
rNext := l.next()
if rNext == eof {
return false
}
rDelim, size := utf8.DecodeRuneInString(rightDelim)
if rNext != rDelim {
return false
}
rightDelim = rightDelim[size:]
}
return false
return true
}

// lexChar scans a character constant. The initial quote is already
Expand Down
16 changes: 16 additions & 0 deletions src/text/template/parse/lex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,22 @@ func TestDelims(t *testing.T) {
}
}

func TestDelimsAlphaNumeric(t *testing.T) {
test := lexTest{"right delimiter with alphanumeric start", "{{hub .host hub}}", []item{
mkItem(itemLeftDelim, "{{hub"),
mkItem(itemSpace, " "),
mkItem(itemField, ".host"),
mkItem(itemSpace, " "),
mkItem(itemRightDelim, "hub}}"),
tEOF,
}}
items := collect(&test, "{{hub", "hub}}")

if !equal(items, test.items, false) {
t.Errorf("%s: got\n\t%v\nexpected\n\t%v", test.name, items, test.items)
}
}

var lexPosTests = []lexTest{
{"empty", "", []item{{itemEOF, 0, "", 1}}},
{"punctuation", "{{,@%#}}", []item{
Expand Down

0 comments on commit 9a6acc8

Please sign in to comment.