Skip to content

Commit 6277656

Browse files
committed
html, exp/html: escape ' and " as ' and ", since IE8 and
below do not support '. This makes package html consistent with package text/template's HTMLEscape function. Fixes #3489. R=rsc, mikesamuel, dsymonds CC=golang-dev https://golang.org/cl/5992071
1 parent 772e8ff commit 6277656

File tree

6 files changed

+22
-15
lines changed

6 files changed

+22
-15
lines changed

src/pkg/exp/html/escape.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,15 @@ func escape(w writer, s string) error {
205205
case '&':
206206
esc = "&"
207207
case '\'':
208-
esc = "'"
208+
// "'" is shorter than "'" and apos was not in HTML until HTML5.
209+
esc = "'"
209210
case '<':
210211
esc = "&lt;"
211212
case '>':
212213
esc = "&gt;"
213214
case '"':
214-
esc = "&quot;"
215+
// "&#34;" is shorter than "&quot;".
216+
esc = "&#34;"
215217
default:
216218
panic("unrecognized escape character")
217219
}
@@ -226,7 +228,7 @@ func escape(w writer, s string) error {
226228
}
227229

228230
// EscapeString escapes special characters like "<" to become "&lt;". It
229-
// escapes only five such characters: amp, apos, lt, gt and quot.
231+
// escapes only five such characters: <, >, &, ' and ".
230232
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
231233
// always true.
232234
func EscapeString(s string) string {

src/pkg/exp/html/render_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func TestRenderer(t *testing.T) {
9898
},
9999
},
100100
}
101-
want := `<html><head></head><body>0&lt;1<p id="A" foo="abc&quot;def">` +
101+
want := `<html><head></head><body>0&lt;1<p id="A" foo="abc&#34;def">` +
102102
`2<b empty="">3</b><i backslash="\">&amp;4</i></p>` +
103103
`5<blockquote></blockquote><br/>6</body></html>`
104104
b := new(bytes.Buffer)

src/pkg/exp/html/token_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ var tokenTests = []tokenTest{
359359
{
360360
"tricky",
361361
"<p \t\n iD=\"a&quot;B\" foo=\"bar\"><EM>te&lt;&amp;;xt</em></p>",
362-
`<p id="a&quot;B" foo="bar">$<em>$te&lt;&amp;;xt$</em>$</p>`,
362+
`<p id="a&#34;B" foo="bar">$<em>$te&lt;&amp;;xt$</em>$</p>`,
363363
},
364364
// A nonexistent entity. Tokenizing and converting back to a string should
365365
// escape the "&" to become "&amp;".
@@ -421,7 +421,7 @@ var tokenTests = []tokenTest{
421421
{
422422
"Double-quoted attribute value",
423423
`<input value="I'm an attribute" FOO="BAR">`,
424-
`<input value="I&apos;m an attribute" foo="BAR">`,
424+
`<input value="I&#39;m an attribute" foo="BAR">`,
425425
},
426426
{
427427
"Attribute name characters",
@@ -436,7 +436,7 @@ var tokenTests = []tokenTest{
436436
{
437437
"Attributes with a solitary single quote",
438438
`<p id=can't><p id=won't>`,
439-
`<p id="can&apos;t">$<p id="won&apos;t">`,
439+
`<p id="can&#39;t">$<p id="won&#39;t">`,
440440
},
441441
}
442442

@@ -545,10 +545,11 @@ func TestUnescapeEscape(t *testing.T) {
545545
`"<&>"`,
546546
`&quot;&lt;&amp;&gt;&quot;`,
547547
`3&5==1 && 0<1, "0&lt;1", a+acute=&aacute;`,
548+
`The special characters are: <, >, &, ' and "`,
548549
}
549550
for _, s := range ss {
550-
if s != UnescapeString(EscapeString(s)) {
551-
t.Errorf("s != UnescapeString(EscapeString(s)), s=%q", s)
551+
if got := UnescapeString(EscapeString(s)); got != s {
552+
t.Errorf("got %q want %q", got, s)
552553
}
553554
}
554555
}

src/pkg/html/escape.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,15 @@ func escape(w writer, s string) error {
210210
case '&':
211211
esc = "&amp;"
212212
case '\'':
213-
esc = "&apos;"
213+
// "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
214+
esc = "&#39;"
214215
case '<':
215216
esc = "&lt;"
216217
case '>':
217218
esc = "&gt;"
218219
case '"':
219-
esc = "&quot;"
220+
// "&#34;" is shorter than "&quot;".
221+
esc = "&#34;"
220222
default:
221223
panic("unrecognized escape character")
222224
}
@@ -231,7 +233,7 @@ func escape(w writer, s string) error {
231233
}
232234

233235
// EscapeString escapes special characters like "<" to become "&lt;". It
234-
// escapes only five such characters: amp, apos, lt, gt and quot.
236+
// escapes only five such characters: <, >, &, ' and ".
235237
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
236238
// always true.
237239
func EscapeString(s string) string {

src/pkg/net/http/server.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,10 @@ var htmlReplacer = strings.NewReplacer(
785785
"&", "&amp;",
786786
"<", "&lt;",
787787
">", "&gt;",
788-
`"`, "&quot;",
789-
"'", "&apos;",
788+
// "&#34;" is shorter than "&quot;".
789+
`"`, "&#34;",
790+
// "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
791+
"'", "&#39;",
790792
)
791793

792794
func htmlEscape(s string) string {

src/pkg/text/template/funcs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ func not(arg interface{}) (truth bool) {
246246

247247
var (
248248
htmlQuot = []byte("&#34;") // shorter than "&quot;"
249-
htmlApos = []byte("&#39;") // shorter than "&apos;"
249+
htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
250250
htmlAmp = []byte("&amp;")
251251
htmlLt = []byte("&lt;")
252252
htmlGt = []byte("&gt;")

0 commit comments

Comments
 (0)