diff --git a/src/html/template/example_test.go b/src/html/template/example_test.go index 533c0dd961..9d965f1943 100644 --- a/src/html/template/example_test.go +++ b/src/html/template/example_test.go @@ -116,9 +116,9 @@ func Example_escape() { // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner"32<tasty@example.com> - // \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran & Freddie\'s Diner\"32\x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\"32\x3Ctasty@example.com\x3E // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E } diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index 2b299b0bf6..aa5cd4c552 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -909,6 +909,8 @@ func TestJSEscaping(t *testing.T) { {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, {"unprintable \uFDFF", `unprintable \uFDFF`}, {``, `\x3Chtml\x3E`}, + {`no = in attributes`, `no \x3D in attributes`}, + {`' does not become HTML entity`, `\x26#x27; does not become HTML entity`}, } for _, tc := range testCases { s := JSEscapeString(tc.in) diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go index 0985eda317..0568c798a8 100644 --- a/src/text/template/funcs.go +++ b/src/text/template/funcs.go @@ -642,6 +642,8 @@ var ( jsQuot = []byte(`\"`) jsLt = []byte(`\x3C`) jsGt = []byte(`\x3E`) + jsAmp = []byte(`\x26`) + jsEq = []byte(`\x3D`) ) // JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. @@ -670,6 +672,10 @@ func JSEscape(w io.Writer, b []byte) { w.Write(jsLt) case '>': w.Write(jsGt) + case '&': + w.Write(jsAmp) + case '=': + w.Write(jsEq) default: w.Write(jsLowUni) t, b := c>>4, c&0x0f @@ -704,7 +710,7 @@ func JSEscapeString(s string) string { func jsIsSpecial(r rune) bool { switch r { - case '\\', '\'', '"', '<', '>': + case '\\', '\'', '"', '<', '>', '&', '=': return true } return r < ' ' || utf8.RuneSelf <= r