NOTE: keep in sync with string above.
(s []byte, escapeHTML bool)
| 958 | |
| 959 | // NOTE: keep in sync with string above. |
| 960 | func (e *encodeState) stringBytes(s []byte, escapeHTML bool) { |
| 961 | e.WriteByte('"') |
| 962 | start := 0 |
| 963 | for i := 0; i < len(s); { |
| 964 | if b := s[i]; b < utf8.RuneSelf { |
| 965 | if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { |
| 966 | i++ |
| 967 | continue |
| 968 | } |
| 969 | if start < i { |
| 970 | e.Write(s[start:i]) |
| 971 | } |
| 972 | e.WriteByte('\\') |
| 973 | switch b { |
| 974 | case '\\', '"': |
| 975 | e.WriteByte(b) |
| 976 | case '\n': |
| 977 | e.WriteByte('n') |
| 978 | case '\r': |
| 979 | e.WriteByte('r') |
| 980 | case '\t': |
| 981 | e.WriteByte('t') |
| 982 | default: |
| 983 | // This encodes bytes < 0x20 except for \t, \n and \r. |
| 984 | // If escapeHTML is set, it also escapes <, >, and & |
| 985 | // because they can lead to security holes when |
| 986 | // user-controlled strings are rendered into JSON |
| 987 | // and served to some browsers. |
| 988 | e.WriteString(`u00`) |
| 989 | e.WriteByte(hex[b>>4]) |
| 990 | e.WriteByte(hex[b&0xF]) |
| 991 | } |
| 992 | i++ |
| 993 | start = i |
| 994 | continue |
| 995 | } |
| 996 | c, size := utf8.DecodeRune(s[i:]) |
| 997 | if c == utf8.RuneError && size == 1 { |
| 998 | if start < i { |
| 999 | e.Write(s[start:i]) |
| 1000 | } |
| 1001 | e.WriteString(`\ufffd`) |
| 1002 | i += size |
| 1003 | start = i |
| 1004 | continue |
| 1005 | } |
| 1006 | // U+2028 is LINE SEPARATOR. |
| 1007 | // U+2029 is PARAGRAPH SEPARATOR. |
| 1008 | // They are both technically valid characters in JSON strings, |
| 1009 | // but don't work in JSONP, which has to be evaluated as JavaScript, |
| 1010 | // and can lead to security holes there. It is valid JSON to |
| 1011 | // escape them, so we do so unconditionally. |
| 1012 | // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. |
| 1013 | if c == '\u2028' || c == '\u2029' { |
| 1014 | if start < i { |
| 1015 | e.Write(s[start:i]) |
| 1016 | } |
| 1017 | e.WriteString(`\u202`) |
no outgoing calls
no test coverage detected