diff options
| author | mprahl <mprahl@redhat.com> | 2022-04-05 15:06:33 -0400 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2022-04-06 22:27:40 +0000 |
| commit | 9a6acc83c853c17700c44e336e2d3e2c0fe9a72b (patch) | |
| tree | 95999723a876ad00041341d8ff75ecaea8c727fc /src/text/template/parse | |
| parent | 81ae993e54547415ba674082801b05961e3f2aa3 (diff) | |
| download | go-9a6acc83c853c17700c44e336e2d3e2c0fe9a72b.tar.xz | |
text/template: support delimiters that can be confused with actions
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 <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Trust: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/text/template/parse')
| -rw-r--r-- | src/text/template/parse/lex.go | 24 | ||||
| -rw-r--r-- | src/text/template/parse/lex_test.go | 16 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go index 40d0411121..078f714ccf 100644 --- a/src/text/template/parse/lex.go +++ b/src/text/template/parse/lex.go @@ -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 diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go index df6aabffb2..fcb7e8eacd 100644 --- a/src/text/template/parse/lex_test.go +++ b/src/text/template/parse/lex_test.go @@ -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{ |
