mirror of
https://github.com/golang/go
synced 2024-11-16 23:34:41 -07:00
text/template/parse: fix data race on lexer initialization
Before this change, `startParse` would write `lex.breakOK` and `lex.continueOK` when the lexer goroutine is already running, which is a potential race condition. Makes `breakOK` and `continueOK` configuration flags passed when `lexer` is created, similarly to how `emitComment` works. Fixes #53234 Change-Id: Ia65f6135509a758cd4c5a453b249a174f4fb3e21 Reviewed-on: https://go-review.googlesource.com/c/go/+/410414 Reviewed-by: Eli Bendersky <eliben@google.com> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
47e34ca533
commit
9ce28b518d
@ -211,7 +211,7 @@ func (l *lexer) drain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lex creates a new scanner for the input string.
|
// lex creates a new scanner for the input string.
|
||||||
func lex(name, input, left, right string, emitComment bool) *lexer {
|
func lex(name, input, left, right string, emitComment, breakOK, continueOK bool) *lexer {
|
||||||
if left == "" {
|
if left == "" {
|
||||||
left = leftDelim
|
left = leftDelim
|
||||||
}
|
}
|
||||||
@ -224,6 +224,8 @@ func lex(name, input, left, right string, emitComment bool) *lexer {
|
|||||||
leftDelim: left,
|
leftDelim: left,
|
||||||
rightDelim: right,
|
rightDelim: right,
|
||||||
emitComment: emitComment,
|
emitComment: emitComment,
|
||||||
|
breakOK: breakOK,
|
||||||
|
continueOK: continueOK,
|
||||||
items: make(chan item),
|
items: make(chan item),
|
||||||
line: 1,
|
line: 1,
|
||||||
startLine: 1,
|
startLine: 1,
|
||||||
|
@ -394,7 +394,7 @@ var lexTests = []lexTest{
|
|||||||
|
|
||||||
// collect gathers the emitted items into a slice.
|
// collect gathers the emitted items into a slice.
|
||||||
func collect(t *lexTest, left, right string) (items []item) {
|
func collect(t *lexTest, left, right string) (items []item) {
|
||||||
l := lex(t.name, t.input, left, right, true)
|
l := lex(t.name, t.input, left, right, true, true, true)
|
||||||
for {
|
for {
|
||||||
item := l.nextItem()
|
item := l.nextItem()
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
@ -550,7 +550,7 @@ func TestPos(t *testing.T) {
|
|||||||
func TestShutdown(t *testing.T) {
|
func TestShutdown(t *testing.T) {
|
||||||
// We need to duplicate template.Parse here to hold on to the lexer.
|
// We need to duplicate template.Parse here to hold on to the lexer.
|
||||||
const text = "erroneous{{define}}{{else}}1234"
|
const text = "erroneous{{define}}{{else}}1234"
|
||||||
lexer := lex("foo", text, "{{", "}}", false)
|
lexer := lex("foo", text, "{{", "}}", false, true, true)
|
||||||
_, err := New("root").parseLexer(lexer)
|
_, err := New("root").parseLexer(lexer)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected error")
|
t.Fatalf("expected error")
|
||||||
|
@ -224,8 +224,6 @@ func (t *Tree) startParse(funcs []map[string]any, lex *lexer, treeSet map[string
|
|||||||
t.vars = []string{"$"}
|
t.vars = []string{"$"}
|
||||||
t.funcs = funcs
|
t.funcs = funcs
|
||||||
t.treeSet = treeSet
|
t.treeSet = treeSet
|
||||||
lex.breakOK = !t.hasFunction("break")
|
|
||||||
lex.continueOK = !t.hasFunction("continue")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stopParse terminates parsing.
|
// stopParse terminates parsing.
|
||||||
@ -244,7 +242,10 @@ func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tre
|
|||||||
defer t.recover(&err)
|
defer t.recover(&err)
|
||||||
t.ParseName = t.Name
|
t.ParseName = t.Name
|
||||||
emitComment := t.Mode&ParseComments != 0
|
emitComment := t.Mode&ParseComments != 0
|
||||||
t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, emitComment), treeSet)
|
breakOK := !t.hasFunction("break")
|
||||||
|
continueOK := !t.hasFunction("continue")
|
||||||
|
lexer := lex(t.Name, text, leftDelim, rightDelim, emitComment, breakOK, continueOK)
|
||||||
|
t.startParse(funcs, lexer, treeSet)
|
||||||
t.text = text
|
t.text = text
|
||||||
t.parse()
|
t.parse()
|
||||||
t.add()
|
t.add()
|
||||||
|
Loading…
Reference in New Issue
Block a user