]> Cypherpunks.ru repositories - gostls13.git/commitdiff
text/template: support delimiters that can be confused with actions
authormprahl <mprahl@redhat.com>
Tue, 5 Apr 2022 19:06:33 +0000 (15:06 -0400)
committerIan Lance Taylor <iant@golang.org>
Wed, 6 Apr 2022 22:27:40 +0000 (22:27 +0000)
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>

src/text/template/parse/lex.go
src/text/template/parse/lex_test.go

index 40d0411121b7c9d1c9dced7f1282621796e0dd16..078f714ccf5bfa95186d81b5af87ce55ff5d0dd6 100644 (file)
@@ -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
index df6aabffb20e13c9010faf779a0b190bf8d43ac4..fcb7e8eacddeb7a1fccbdfc30feec7daa4dc46d0 100644 (file)
@@ -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{