diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index a39d696..0c56d6c 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -745,6 +745,26 @@
`<meta http-equiv="refresh" content="{{"asd: 123"}}">`,
`<meta http-equiv="refresh" content="asd: 123">`,
},
+ {
+ "meta content url with whitespace before equals",
+ `<meta http-equiv="refresh" content="0;url ={{"javascript:alert(1)"}}">`,
+ `<meta http-equiv="refresh" content="0;url =#ZgotmplZ">`,
+ },
+ {
+ "meta content url with tab before equals",
+ "<meta http-equiv=\"refresh\" content=\"0;url\t={{\"javascript:alert(1)\"}}\">",
+ "<meta http-equiv=\"refresh\" content=\"0;url\t=#ZgotmplZ\">",
+ },
+ {
+ "meta content url with space after equals",
+ `<meta http-equiv="refresh" content="0;url= {{"javascript:alert(1)"}}">`,
+ `<meta http-equiv="refresh" content="0;url= #ZgotmplZ">`,
+ },
+ {
+ "meta content url with whitespace both sides of equals",
+ "<meta http-equiv=\"refresh\" content=\"0;url \t= {{\"javascript:alert(1)\"}}\">",
+ "<meta http-equiv=\"refresh\" content=\"0;url \t= #ZgotmplZ\">",
+ },
}
for _, test := range tests {
diff --git a/src/html/template/transition.go b/src/html/template/transition.go
index 7fbab1d..ea4b272 100644
--- a/src/html/template/transition.go
+++ b/src/html/template/transition.go
@@ -626,10 +626,12 @@
// 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 @@
// 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