HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 so that the JSON will be safe to embed inside HTML tags. For historical reasons, web browsers don't honor standard HTML escaping
(dst *bytes.Buffer, src []byte)
| 191 | // escaping within <script> tags, so an alternative JSON encoding must |
| 192 | // be used. |
| 193 | func HTMLEscape(dst *bytes.Buffer, src []byte) { |
| 194 | // The characters can only appear in string literals, |
| 195 | // so just scan the string one byte at a time. |
| 196 | start := 0 |
| 197 | for i, c := range src { |
| 198 | if c == '<' || c == '>' || c == '&' { |
| 199 | if start < i { |
| 200 | dst.Write(src[start:i]) |
| 201 | } |
| 202 | dst.WriteString(`\u00`) |
| 203 | dst.WriteByte(hex[c>>4]) |
| 204 | dst.WriteByte(hex[c&0xF]) |
| 205 | start = i + 1 |
| 206 | } |
| 207 | // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). |
| 208 | if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { |
| 209 | if start < i { |
| 210 | dst.Write(src[start:i]) |
| 211 | } |
| 212 | dst.WriteString(`\u202`) |
| 213 | dst.WriteByte(hex[src[i+2]&0xF]) |
| 214 | start = i + 3 |
| 215 | } |
| 216 | } |
| 217 | if start < len(src) { |
| 218 | dst.Write(src[start:]) |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | // Marshaler is the interface implemented by types that |
| 223 | // can marshal themselves into valid JSON. |