Hầu hết các thư viện cung cấp thoát mọi thứ họ có thể, bao gồm hàng trăm ký hiệu và hàng ngàn ký tự không phải ASCII không phải là thứ bạn muốn trong thế giới UTF-8.
Ngoài ra, như Jeff Williams đã lưu ý, không có tùy chọn nào thoát khỏi HTML HTML, có một số bối cảnh.
Giả sử bạn không bao giờ sử dụng các thuộc tính không được trích dẫn và hãy nhớ rằng các bối cảnh khác nhau tồn tại, nó đã viết phiên bản của riêng tôi:
private static final long BODY_ESCAPE =
1L << '&' | 1L << '<' | 1L << '>';
private static final long DOUBLE_QUOTED_ATTR_ESCAPE =
1L << '"' | 1L << '&' | 1L << '<' | 1L << '>';
private static final long SINGLE_QUOTED_ATTR_ESCAPE =
1L << '"' | 1L << '&' | 1L << '\'' | 1L << '<' | 1L << '>';
// 'quot' and 'apos' are 1 char longer than '#34' and '#39' which I've decided to use
private static final String REPLACEMENTS = ""&'<>";
private static final int REPL_SLICES = /* |0, 5, 10, 15, 19, 23*/
5<<5 | 10<<10 | 15<<15 | 19<<20 | 23<<25;
// These 5-bit numbers packed into a single int
// are indices within REPLACEMENTS which is a 'flat' String[]
private static void appendEscaped(
StringBuilder builder,
CharSequence content,
long escapes // pass BODY_ESCAPE or *_QUOTED_ATTR_ESCAPE here
) {
int startIdx = 0, len = content.length();
for (int i = 0; i < len; i++) {
char c = content.charAt(i);
long one;
if (((c & 63) == c) && ((one = 1L << c) & escapes) != 0) {
// -^^^^^^^^^^^^^^^ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// | | take only dangerous characters
// | java shifts longs by 6 least significant bits,
// | e. g. << 0b110111111 is same as >> 0b111111.
// | Filter out bigger characters
int index = Long.bitCount(SINGLE_QUOTED_ATTR_ESCAPE & (one - 1));
builder.append(content, startIdx, i /* exclusive */)
.append(REPLACEMENTS,
REPL_SLICES >>> 5*index & 31,
REPL_SLICES >>> 5*(index+1) & 31);
startIdx = i + 1;
}
}
builder.append(content, startIdx, len);
}
Xem xét dán sao chép từ Gist mà không giới hạn độ dài dòng .