jhy/jsoup — Issue #150: Over-zealous escaping of characters within attribute values
Author: helsom
Created: 2011-12-02 16:49:23+00:00
State: open

I've raised as a separate issue the need to be able to pass the escape mode to the Jsoup.clean() function. Well leading on from that, if the escape mode is set to "extended", I am finding that too many characters end up being escaped within an attribute's value.

For example, style="margin-left:40px;" would end up as style="margin-left:40px;".

I'm thinking that only the < > " ' and & characters need to be escaped? For URLs and the like.

Test Case:

@Test public void inAttributeEscaping_Extended() {
String html = "

Paragraph one Link

";
ExtendedWhitelist whitelist = ExtendedWhitelist.none();
whitelist
.addTags("p","a")
.addAttributes("p","style")
.addAttributes("a","href");
String clean = Jsoup.clean(html, whitelist, false, "extended");
assertEquals("

Paragraph one Link

", clean);
}

I've fixed this locally by adding an "inAttribute" argument to the escape() function within Entities.java, as follows, and passing in true for this argument at line 76 within Attribute.java, in the html() function.

static String escape(String string, CharsetEncoder encoder, EscapeMode escapeMode, boolean inAttribute) {
StringBuilder accum = new StringBuilder(string.length() * 2);
Map map = escapeMode.getMap();
Map xhtmlMap = Entities.EscapeMode.xhtml.getMap();

for (int pos = 0; pos < string.length(); pos++) {
Character c = string.charAt(pos);
if (map.containsKey(c) && (!inAttribute || xhtmlMap.containsKey(c)))
accum.append('&').append(map.get(c)).append(';');
else if (encoder.canEncode(c))
accum.append(c.charValue());
else
accum.append("&#").append((int) c).append(';');
}

return accum.toString();
}