mirror of
https://github.com/golang/go
synced 2024-11-12 06:20:22 -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])
|
b.Write(s[written:cs])
|
||||||
written = i1
|
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
|
c, i = c1, i1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,6 +904,10 @@ func TestErrors(t *testing.T) {
|
|||||||
`<a style=font:'Arial'>`,
|
`<a style=font:'Arial'>`,
|
||||||
`exp/template/html:z: "'" in unquoted attr: "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 {
|
for _, test := range tests {
|
||||||
|
@ -100,26 +100,30 @@ func tTag(c context, s []byte) (context, int) {
|
|||||||
return context{state: stateError, err: err}, len(s)
|
return context{state: stateError, err: err}, len(s)
|
||||||
}
|
}
|
||||||
state, attr := stateTag, attrNone
|
state, attr := stateTag, attrNone
|
||||||
if i != j {
|
if i == j {
|
||||||
canonAttrName := strings.ToLower(string(s[i:j]))
|
return context{
|
||||||
switch attrType[canonAttrName] {
|
state: stateError,
|
||||||
case contentTypeURL:
|
err: errorf(ErrBadHTML, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
|
||||||
attr = attrURL
|
}, len(s)
|
||||||
case contentTypeCSS:
|
}
|
||||||
attr = attrStyle
|
canonAttrName := strings.ToLower(string(s[i:j]))
|
||||||
case contentTypeJS:
|
switch attrType[canonAttrName] {
|
||||||
|
case contentTypeURL:
|
||||||
|
attr = attrURL
|
||||||
|
case contentTypeCSS:
|
||||||
|
attr = attrStyle
|
||||||
|
case contentTypeJS:
|
||||||
|
attr = attrScript
|
||||||
|
default:
|
||||||
|
if strings.HasPrefix(canonAttrName, "on") {
|
||||||
attr = attrScript
|
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
|
return context{state: state, element: c.element, attr: attr}, j
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user