diff -r 937aa020c667 -r bd51ca92c013 src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java --- a/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java Tue May 14 10:14:55 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java Tue May 14 10:14:55 2013 -0700 @@ -78,8 +78,8 @@ */ public void addAttr(HtmlAttr attrName, String attrValue) { if (attrs.isEmpty()) - attrs = new LinkedHashMap(); - attrs.put(nullCheck(attrName), nullCheck(attrValue)); + attrs = new LinkedHashMap(3); + attrs.put(nullCheck(attrName), escapeHtmlChars(attrValue)); } /** @@ -131,6 +131,35 @@ } /** + * Given a string, escape all special html characters and + * return the result. + * + * @param s The string to check. + * @return the original string with all of the HTML characters escaped. + */ + private static String escapeHtmlChars(String s) { + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch (ch) { + // only start building a new string if we need to + case '<': case '>': case '&': + StringBuilder sb = new StringBuilder(s.substring(0, i)); + for ( ; i < s.length(); i++) { + ch = s.charAt(i); + switch (ch) { + case '<': sb.append("<"); break; + case '>': sb.append(">"); break; + case '&': sb.append("&"); break; + default: sb.append(ch); break; + } + } + return sb.toString(); + } + } + return s; + } + + /** * Generates an HTML anchor tag. * * @param ref reference url for the anchor tag @@ -139,7 +168,7 @@ */ public static HtmlTree A(String ref, Content body) { HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body)); - htmltree.addAttr(HtmlAttr.HREF, Util.escapeHtmlChars(nullCheck(ref))); + htmltree.addAttr(HtmlAttr.HREF, ref); return htmltree; } @@ -324,7 +353,7 @@ HtmlStyle styleClass, Content body) { HtmlTree htmltree = new HtmlTree(headingTag, nullCheck(body)); if (printTitle) - htmltree.addAttr(HtmlAttr.TITLE, Util.stripHtml(body.toString())); + htmltree.addAttr(HtmlAttr.TITLE, stripHtml(body)); if (styleClass != null) htmltree.addStyle(styleClass); return htmltree; @@ -837,4 +866,22 @@ return false; } } + + /** + * Given a Content node, strips all html characters and + * return the result. + * + * @param body The content node to check. + * @return the plain text from the content node + * + */ + private static String stripHtml(Content body) { + String rawString = body.toString(); + // remove HTML tags + rawString = rawString.replaceAll("\\<.*?>", " "); + // consolidate multiple spaces between a word to a single space + rawString = rawString.replaceAll("\\b\\s{2,}\\b", " "); + // remove extra whitespaces + return rawString.trim(); + } }