diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index aef5e01957..5ff1734202 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -760,6 +760,26 @@ func TestEscape(t *testing.T) {
``,
``,
},
+ {
+ "meta content url with whitespace before equals",
+ ``,
+ ``,
+ },
+ {
+ "meta content url with tab before equals",
+ "",
+ "",
+ },
+ {
+ "meta content url with space after equals",
+ ``,
+ ``,
+ },
+ {
+ "meta content url with whitespace both sides of equals",
+ "",
+ "",
+ },
}
for _, test := range tests {
diff --git a/src/html/template/transition.go b/src/html/template/transition.go
index 7fbab1df7b..ea4b272cc2 100644
--- a/src/html/template/transition.go
+++ b/src/html/template/transition.go
@@ -626,10 +626,12 @@ func tError(c context, s []byte) (context, int) {
// tMetaContent is the context transition function for the meta content attribute state.
func tMetaContent(c context, s []byte) (context, int) {
- for i := 0; i < len(s); i++ {
- if i+3 <= len(s)-1 && bytes.Equal(bytes.ToLower(s[i:i+4]), []byte("url=")) {
- c.state = stateMetaContentURL
- return c, i + 4
+ for i := range len(s) {
+ if i+3 <= len(s)-1 && bytes.EqualFold(s[i:i+3], []byte("url")) {
+ if j := eatWhiteSpace(s, i+3); j < len(s) && s[j] == '=' {
+ c.state = stateMetaContentURL
+ return c, j + 1
+ }
}
}
return c, len(s)
@@ -637,7 +639,7 @@ func tMetaContent(c context, s []byte) (context, int) {
// tMetaContentURL is the context transition function for the "url=" part of a meta content attribute state.
func tMetaContentURL(c context, s []byte) (context, int) {
- for i := 0; i < len(s); i++ {
+ for i := range len(s) {
if s[i] == ';' {
c.state = stateMetaContent
return c, i + 1