mirror of
https://github.com/golang/go
synced 2024-11-12 06:30:21 -07:00
exp/template/html: fix infinite loop in escapeText on bad input
The template "<a=" caused an infinite loop in escape text. The change to tTag fixes that and the change to escape.go causes escapeText to panic on any infinite loop that does not involve a state cycle. R=nigeltao CC=golang-dev https://golang.org/cl/5115041
This commit is contained in:
parent
66cdd02038
commit
3771415100
@ -598,6 +598,9 @@ func (e *escaper) escapeText(c context, n *parse.TextNode) context {
|
||||
b.Write(s[written:cs])
|
||||
written = i1
|
||||
}
|
||||
if i == i1 && c.state == c1.state {
|
||||
panic(fmt.Sprintf("infinite loop from %v to %v on %q..%q", c, c1, s[:i], s[i:]))
|
||||
}
|
||||
c, i = c1, i1
|
||||
}
|
||||
|
||||
|
@ -904,6 +904,10 @@ func TestErrors(t *testing.T) {
|
||||
`<a style=font:'Arial'>`,
|
||||
`exp/template/html:z: "'" in unquoted attr: "font:'Arial'"`,
|
||||
},
|
||||
{
|
||||
`<a=foo>`,
|
||||
`: expected space, attr name, or end of tag, but got "=foo>"`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -100,26 +100,30 @@ func tTag(c context, s []byte) (context, int) {
|
||||
return context{state: stateError, err: err}, len(s)
|
||||
}
|
||||
state, attr := stateTag, attrNone
|
||||
if i != j {
|
||||
canonAttrName := strings.ToLower(string(s[i:j]))
|
||||
switch attrType[canonAttrName] {
|
||||
case contentTypeURL:
|
||||
attr = attrURL
|
||||
case contentTypeCSS:
|
||||
attr = attrStyle
|
||||
case contentTypeJS:
|
||||
if i == j {
|
||||
return context{
|
||||
state: stateError,
|
||||
err: errorf(ErrBadHTML, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
|
||||
}, len(s)
|
||||
}
|
||||
canonAttrName := strings.ToLower(string(s[i:j]))
|
||||
switch attrType[canonAttrName] {
|
||||
case contentTypeURL:
|
||||
attr = attrURL
|
||||
case contentTypeCSS:
|
||||
attr = attrStyle
|
||||
case contentTypeJS:
|
||||
attr = attrScript
|
||||
default:
|
||||
if strings.HasPrefix(canonAttrName, "on") {
|
||||
attr = attrScript
|
||||
default:
|
||||
if strings.HasPrefix(canonAttrName, "on") {
|
||||
attr = attrScript
|
||||
}
|
||||
}
|
||||
if j == len(s) {
|
||||
state = stateAttrName
|
||||
} else {
|
||||
state = stateAfterName
|
||||
}
|
||||
}
|
||||
if j == len(s) {
|
||||
state = stateAttrName
|
||||
} else {
|
||||
state = stateAfterName
|
||||
}
|
||||
return context{state: state, element: c.element, attr: attr}, j
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user