2017-10-18 13:39 GMT+03:00 <ma...@apache.org>: > Author: markt > Date: Wed Oct 18 10:39:54 2017 > New Revision: 1812489 > > URL: http://svn.apache.org/viewvc?rev=1812489&view=rev > Log: > Refactor XML and HTML escaping to a single location > > Added: > tomcat/trunk/java/org/apache/tomcat/util/security/Escape.java (with > props) > Modified: ...
Good. It's more than I hoped for. Several comments below. > Added: tomcat/trunk/java/org/apache/tomcat/util/security/Escape.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/security/Escape.java?rev=1812489&view=auto > ============================================================================== > --- tomcat/trunk/java/org/apache/tomcat/util/security/Escape.java (added) > +++ tomcat/trunk/java/org/apache/tomcat/util/security/Escape.java Wed Oct 18 > 10:39:54 2017 > @@ -0,0 +1,160 @@ > +/* ... > + */ > +package org.apache.tomcat.util.security; > + > +/** > + * Provides utility methods to escape content for different contexts. It is > + * critical that the escaping used is correct for the context in which the > data > + * is to be used. > + */ > +public class Escape { > + > + /** > + * Escape content for use in HTML. This escaping is suitable for the > + * following uses: > + * <ul> > + * <li>Element content when the escaped data will be placed directly > inside > + * tags such as <p>, <td> etc.</li> > + * <li>Attribute values when the attribute value is quoted with " or > + * '.</li> > + * </ul> > + * > + * @param content The content to escape > + * > + * @return The escaped content or {@code null} if the content was > + * {@code null} > + */ > + public static String htmlElementContent(String content) { > + if (content == null) { > + return null; > + } > + > + StringBuilder sb = new StringBuilder(); > + > + for (int i = 0; i < content.length(); i++) { > + char c = content.charAt(i); > + if (c == '<') { > + sb.append("<"); > + } else if (c == '>') { > + sb.append(">"); > + } else if (c == '\'') { > + sb.append("'"); Writing the above as decimal number will save one character. 'x' sb.append("'"); (Also I wondered whether HTML spec supports hex notation here. In [1] -> 5.3.1 Numeric character references -> Hex numerals are supported. -> a "Note" says that original spec did not have it, but it was added later (in a document dating year 1998) ) [1] https://www.w3.org/TR/1999/REC-html401-19991224/charset.html#h-5.3.1 > + } else if (c == '&') { > + sb.append("&"); > + } else if (c == '"') { > + sb.append("""); > + } else if (c == '/') { > + sb.append("/"); sb.append("/"); > + } else { > + sb.append(c); > + } > + } > + > + return sb.toString(); > + } > + > + > + /** > + * Convert the object to a string via {@link Object#toString()} and HTML > + * escape the resulting string for use in HTMl content. s/HTMl/HTML/ > + * > + * @param obj The object to convert to String and then escape > + * > + * @return The escaped content or <code>"?"</code> if obj is > + * {@code null} > + */ > + public static String htmlElementContext(Object obj) { > + if (obj == null) { > + return "?"; > + } > + > + try { > + return xml(obj.toString()); I think that the above was supposed to be a call to "htmlElementContext()", according to the method name. > + } catch (Exception e) { > + return null; > + } > + } > + > + > + /** > + * Escape content for use in XML. > + * > + * @param content The content to escape > + * > + * @return The escaped content or {@code null} if the content was > + * {@code null} > + */ > + public static String xml(String content) { > + return xml(null, content); > + } > + > + > + /** > + * Escape content for use in XML. > + * > + * @param ifNull The value to return if content is {@code null} > + * @param content The content to escape > + * > + * @return The escaped content or the value of ifNull if the content was > + * {@code null} > + */ > + public static String xml(String ifNull, String content) { > + return xml(ifNull, false, content); > + } > + > + > + /** > + * Escape content for use in XML. > + * > + * @param ifNull The value to return if content is {@code null} > + * @param escapeCRLF Should CR and LF also be escaped? > + * @param content The content to escape > + * > + * @return The escaped content or the value of ifNull if the content was {@code ifNull} > + * {@code null} > + */ > + public static String xml(String ifNull, boolean escapeCRLF, String > content) { > + if (content == null) { > + return ifNull; > + } > + > + StringBuilder sb = new StringBuilder(); > + > + for (int i = 0; i < content.length(); i++) { > + char c = content.charAt(i); > + if (c == '<') { > + sb.append("<"); > + } else if (c == '>') { > + sb.append(">"); > + } else if (c == '\'') { > + sb.append("'"); > + } else if (c == '&') { > + sb.append("&"); > + } else if (c == '"') { > + sb.append("""); > + } else if (escapeCRLF && c == '\r') { > + sb.append(" "); > + } else if (escapeCRLF && c == '\n') { > + sb.append(" "); > + } else { > + sb.append(c); > + } > + } > + > + return sb.toString(); Maybe sb.length() > content.length() ? sb.toString() : content > + } > +} Best regards, Konstantin Kolinko --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org