Commit 582bb304 authored by Mike Samuel's avatar Mike Samuel

exp/template/html: don't normalize '<' in doctypes.

The normalization that prevents element name and comment injection in
  <{{.}}
by converting it to
  &lt;{{.}}
breaks
  <!DOCTYPE html>

Instead of splitting states to have a start of document state and a text
state, I whitelist <!DOCTYPE.

R=nigeltao
CC=golang-dev
https://golang.org/cl/5131051
parent 9aae6482
...@@ -549,6 +549,8 @@ var delimEnds = [...]string{ ...@@ -549,6 +549,8 @@ var delimEnds = [...]string{
delimSpaceOrTagEnd: " \t\n\f\r>", delimSpaceOrTagEnd: " \t\n\f\r>",
} }
var doctypeBytes = []byte("<!DOCTYPE")
// escapeText escapes a text template node. // escapeText escapes a text template node.
func (e *escaper) escapeText(c context, n *parse.TextNode) context { func (e *escaper) escapeText(c context, n *parse.TextNode) context {
s, written, i, b := n.Text, 0, 0, new(bytes.Buffer) s, written, i, b := n.Text, 0, 0, new(bytes.Buffer)
...@@ -566,7 +568,7 @@ func (e *escaper) escapeText(c context, n *parse.TextNode) context { ...@@ -566,7 +568,7 @@ func (e *escaper) escapeText(c context, n *parse.TextNode) context {
} }
} }
for j := i; j < end; j++ { for j := i; j < end; j++ {
if s[j] == '<' { if s[j] == '<' && !bytes.HasPrefix(s[j:], doctypeBytes) {
b.Write(s[written:j]) b.Write(s[written:j])
b.WriteString("&lt;") b.WriteString("&lt;")
written = j + 1 written = j + 1
......
...@@ -420,6 +420,16 @@ func TestEscape(t *testing.T) { ...@@ -420,6 +420,16 @@ func TestEscape(t *testing.T) {
"a<<!-- --><!-- -->b", "a<<!-- --><!-- -->b",
"a&lt;b", "a&lt;b",
}, },
{
"HTML doctype not normalized",
"<!DOCTYPE html>Hello, World!",
"<!DOCTYPE html>Hello, World!",
},
{
"No doctype injection",
`<!{{"DOCTYPE"}}`,
"&lt;!DOCTYPE",
},
{ {
"Split HTML comment", "Split HTML comment",
"<b>Hello, <!-- name of {{if .T}}city -->{{.C}}{{else}}world -->{{.W}}{{end}}</b>", "<b>Hello, <!-- name of {{if .T}}city -->{{.C}}{{else}}world -->{{.W}}{{end}}</b>",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment