Çoğu kütüphane, UTF-8 dünyasında istediğiniz gibi olmayan yüzlerce sembol ve binlerce ASCII olmayan karakter de dahil olmak üzere ellerinden gelebilecek her şeyi kaçırmayı öneriyor.
Ayrıca, Jeff Williams'ın belirttiği gibi, tek bir “kaçış HTML” seçeneği yoktur, birkaç bağlam vardır.
Hiçbir zaman alıntılanmamış nitelikleri kullanmadığınızı ve farklı bağlamların mevcut olduğunu göz önünde bulundurarak, kendi sürümümü yazdı:
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);
}
Çizgi uzunluğu sınırı olmadan Gist'ten kopya yapıştırmayı düşünün .