From do-not-reply at jboss.org Thu Sep 29 04:08:25 2011 Content-Type: multipart/mixed; boundary="===============2620492953244463295==" MIME-Version: 1.0 From: do-not-reply at jboss.org To: gatein-commits at lists.jboss.org Subject: [gatein-commits] gatein SVN: r7556 - in portal/branches/xss/component/common/src: test/java/org/exoplatform/commons/utils and 1 other directory. Date: Thu, 29 Sep 2011 04:08:24 -0400 Message-ID: <201109290808.p8T88OW9014702@svn01.web.mwc.hst.phx2.redhat.com> --===============2620492953244463295== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: trong.tran Date: 2011-09-29 04:08:23 -0400 (Thu, 29 Sep 2011) New Revision: 7556 Added: portal/branches/xss/component/common/src/main/java/org/exoplatform/commo= ns/utils/HTMLEntityEncoder.java portal/branches/xss/component/common/src/test/java/org/exoplatform/commo= ns/utils/TestHTMLEntityEncoder.java Log: Introduce an encoder for HTML entity Added: portal/branches/xss/component/common/src/main/java/org/exoplatform/c= ommons/utils/HTMLEntityEncoder.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- portal/branches/xss/component/common/src/main/java/org/exoplatform/comm= ons/utils/HTMLEntityEncoder.java (rev 0) +++ portal/branches/xss/component/common/src/main/java/org/exoplatform/comm= ons/utils/HTMLEntityEncoder.java 2011-09-29 08:08:23 UTC (rev 7556) @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2011 eXo Platform SAS. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.commons.utils; + +import org.gatein.common.io.WriterCharWriter; +import org.gatein.common.text.CharWriter; +import org.gatein.common.text.EncodingException; +import org.gatein.common.util.ParameterValidation; + +import java.io.StringWriter; +import java.io.Writer; + +/** + * This encoder provides a few methods to encode the String to its HTML en= tity representation. + * = + * @author Trong Tran + * @version $Revision$ + */ +public class HTMLEntityEncoder +{ + private static volatile HTMLEntityEncoder singletonInstance; + + public static HTMLEntityEncoder getInstance() + { + if (singletonInstance =3D=3D null) + { + synchronized (HTMLEntityEncoder.class) + { + if (singletonInstance =3D=3D null) + { + singletonInstance =3D new HTMLEntityEncoder(); + } + } + } + return singletonInstance; + } + = + /** . */ + private final String[] hexToEntity =3D buildHexEntityNumberArray(); + + /** . */ + private final String[] charToEntityName =3D buildEntityNameArray(); + + /** + * Character set that are immune from encoding in HTML + */ + private static final char[] IMMUNE_HTML =3D { ',', '.', '-', '_', ' ' }; + = + /** + * Character set that are immune from encoding in HTML Attribute + */ + private static final char[] IMMUNE_HTMLATTR =3D { ',', '.', '-', '_' }; + + /** + * Encode data for use in HTML + * = + * @param input the string to encode for HTML + * @return input encoded for HTML + */ + public String encodeHTML(String input) + { + return encode(input, IMMUNE_HTML); + } + + /** + * Encode data for use in HTML attributes. + * = + * @param input the string to encode for a HTML attribute + * @return input encoded for use as value of a HTML attribute + */ + public String encodeHTMLAttribute(String input) + { + return encode(input, IMMUNE_HTMLATTR); + } + + /** + * @param chars the array to encode + * @param off the offset in the chars array + * @param len the length of chars to encode + * @param writer the writer to use + * @param immune the characters array are immune from encoding + * @throws EncodingException + */ + protected void safeEncode(char[] chars, int off, int len, CharWriter wr= iter, char[] immune) throws EncodingException + { + + // The index of the last copied char + int previous =3D off; + + // + int to =3D off + len; + + // Perform lookup char by char + for (int current =3D off; current < to; current++) + { + char c =3D chars[current]; + + // Lookup + if (isImmutable(immune, c)) + { + continue; + } + + String replacement; + + String hex; + + // Do we have a replacement + if ((replacement =3D lookupEntityName(c)) !=3D null) + { + // We lazy create the result + + // Append the previous chars if any + writer.append(chars, previous, current - previous); + + // Append the replaced entity + writer.append('&').append(replacement).append(';'); + + // Update the previous pointer + previous =3D current + 1; + } + else if ((hex =3D lookupHexEntityNumber(c)) !=3D null) + { + // We lazy create the result + + // Append the previous chars if any + writer.append(chars, previous, current - previous); + + // Append the replaced entity + writer.append("&#x").append(hex).append(';'); + + // Update the previous pointer + previous =3D current + 1; + } + } + + // + writer.append(chars, previous, chars.length - previous); + } + + protected final String lookupEntityName(char c) + { + return charToEntityName[c]; + } + + protected final String lookupHexEntityNumber(char c) + { + if (c < 0xFF) + { + return hexToEntity[c]; + } + + return Integer.toHexString(c); + } + + private boolean isImmutable(char[] array, char c) + { + for (char ch : array) + { + if (c =3D=3D ch) + return true; + } + return false; + } + + private String encode(String input, char[] immutable) + { + ParameterValidation.throwIllegalArgExceptionIfNull(input, "String"); + + Writer sw =3D new StringWriter(); + CharWriter charWriter =3D new WriterCharWriter(sw); + safeEncode(input.toCharArray(), 0, input.length(), charWriter, immut= able); + return sw.toString(); + } + = + /** + * Set of characters mapped to Entity name + */ + private String[] buildEntityNameArray() + { + String[] ar =3D new String[65536]; + = + ar[34] =3D "quot"; // quotation mark + ar[38] =3D "amp"; // ampersand + ar[60] =3D "lt"; // less-than sign + ar[62] =3D "gt"; // greater-than sign + ar[160] =3D "nbsp"; // no-break space + ar[161] =3D "iexcl"; // inverted exclamation mark + ar[162] =3D "cent"; // cent sign + ar[163] =3D "pound"; // pound sign + ar[164] =3D "curren"; // currency sign + ar[165] =3D "yen"; // yen sign + ar[166] =3D "brvbar"; // broken bar + ar[167] =3D "sect"; // section sign + ar[168] =3D "uml"; // diaeresis + ar[169] =3D "copy"; // copyright sign + ar[170] =3D "ordf"; // feminine ordinal indicator + ar[171] =3D "laquo"; // left-pointing double angle quotation mark + ar[172] =3D "not"; // not sign + ar[173] =3D "shy"; // soft hyphen + ar[174] =3D "reg"; // registered sign + ar[175] =3D "macr"; // macron + ar[176] =3D "deg"; // degree sign + ar[177] =3D "plusmn"; // plus-minus sign + ar[178] =3D "sup2"; // superscript two + ar[179] =3D "sup3"; // superscript three + ar[180] =3D "acute"; // acute accent + ar[181] =3D "micro"; // micro sign + ar[182] =3D "para"; // pilcrow sign + ar[183] =3D "middot"; // middle dot + ar[184] =3D "cedil"; // cedilla + ar[185] =3D "sup1"; // superscript one + ar[186] =3D "ordm"; // masculine ordinal indicator + ar[187] =3D "raquo"; // right-pointing double angle quotation mark + ar[188] =3D "frac14"; // vulgar fraction one quarter + ar[189] =3D "frac12"; // vulgar fraction one half + ar[190] =3D "frac34"; // vulgar fraction three quarters + ar[191] =3D "iquest"; // inverted question mark + ar[192] =3D "Agrave"; // Latin capital letter a with grave + ar[193] =3D "Aacute"; // Latin capital letter a with acute + ar[194] =3D "Acirc"; // Latin capital letter a with circumflex + ar[195] =3D "Atilde"; // Latin capital letter a with tilde + ar[196] =3D "Auml"; // Latin capital letter a with diaeresis + ar[197] =3D "Aring"; // Latin capital letter a with ring above + ar[198] =3D "AElig"; // Latin capital letter ae + ar[199] =3D "Ccedil"; // Latin capital letter c with cedilla + ar[200] =3D "Egrave"; // Latin capital letter e with grave + ar[201] =3D "Eacute"; // Latin capital letter e with acute + ar[202] =3D "Ecirc"; // Latin capital letter e with circumflex + ar[203] =3D "Euml"; // Latin capital letter e with diaeresis + ar[204] =3D "Igrave"; // Latin capital letter i with grave + ar[205] =3D "Iacute"; // Latin capital letter i with acute + ar[206] =3D "Icirc"; // Latin capital letter i with circumflex + ar[207] =3D "Iuml"; // Latin capital letter i with diaeresis + ar[208] =3D "ETH"; // Latin capital letter eth + ar[209] =3D "Ntilde"; // Latin capital letter n with tilde + ar[210] =3D "Ograve"; // Latin capital letter o with grave + ar[211] =3D "Oacute"; // Latin capital letter o with acute + ar[212] =3D "Ocirc"; // Latin capital letter o with circumflex + ar[213] =3D "Otilde"; // Latin capital letter o with tilde + ar[214] =3D "Ouml"; // Latin capital letter o with diaeresis + ar[215] =3D "times"; // multiplication sign + ar[216] =3D "Oslash"; // Latin capital letter o with stroke + ar[217] =3D "Ugrave"; // Latin capital letter u with grave + ar[218] =3D "Uacute"; // Latin capital letter u with acute + ar[219] =3D "Ucirc"; // Latin capital letter u with circumflex + ar[220] =3D "Uuml"; // Latin capital letter u with diaeresis + ar[221] =3D "Yacute"; // Latin capital letter y with acute + ar[222] =3D "THORN"; // Latin capital letter thorn + ar[223] =3D "szlig"; // Latin small letter sharp sXCOMMAX German E= szett + ar[224] =3D "agrave"; // Latin small letter a with grave + ar[225] =3D "aacute"; // Latin small letter a with acute + ar[226] =3D "acirc"; // Latin small letter a with circumflex + ar[227] =3D "atilde"; // Latin small letter a with tilde + ar[228] =3D "auml"; // Latin small letter a with diaeresis + ar[229] =3D "aring"; // Latin small letter a with ring above + ar[230] =3D "aelig"; // Latin lowercase ligature ae + ar[231] =3D "ccedil"; // Latin small letter c with cedilla + ar[232] =3D "egrave"; // Latin small letter e with grave + ar[233] =3D "eacute"; // Latin small letter e with acute + ar[234] =3D "ecirc"; // Latin small letter e with circumflex + ar[235] =3D "euml"; // Latin small letter e with diaeresis + ar[236] =3D "igrave"; // Latin small letter i with grave + ar[237] =3D "iacute"; // Latin small letter i with acute + ar[238] =3D "icirc"; // Latin small letter i with circumflex + ar[239] =3D "iuml"; // Latin small letter i with diaeresis + ar[240] =3D "eth"; // Latin small letter eth + ar[241] =3D "ntilde"; // Latin small letter n with tilde + ar[242] =3D "ograve"; // Latin small letter o with grave + ar[243] =3D "oacute"; // Latin small letter o with acute + ar[244] =3D "ocirc"; // Latin small letter o with circumflex + ar[245] =3D "otilde"; // Latin small letter o with tilde + ar[246] =3D "ouml"; // Latin small letter o with diaeresis + ar[247] =3D "divide"; // division sign + ar[248] =3D "oslash"; // Latin small letter o with stroke + ar[249] =3D "ugrave"; // Latin small letter u with grave + ar[250] =3D "uacute"; // Latin small letter u with acute + ar[251] =3D "ucirc"; // Latin small letter u with circumflex + ar[252] =3D "uuml"; // Latin small letter u with diaeresis + ar[253] =3D "yacute"; // Latin small letter y with acute + ar[254] =3D "thorn"; // Latin small letter thorn + ar[255] =3D "yuml"; // Latin small letter y with diaeresis + ar[338] =3D "OElig"; // Latin capital ligature oe + ar[339] =3D "oelig"; // Latin small ligature oe + ar[352] =3D "Scaron"; // Latin capital letter s with caron + ar[353] =3D "scaron"; // Latin small letter s with caron + ar[376] =3D "Yuml"; // Latin capital letter y with diaeresis + ar[402] =3D "fnof"; // Latin small letter f with hook + ar[710] =3D "circ"; // modifier letter circumflex accent + ar[732] =3D "tilde"; // small tilde + ar[913] =3D "Alpha"; // Greek capital letter alpha + ar[914] =3D "Beta"; // Greek capital letter beta + ar[915] =3D "Gamma"; // Greek capital letter gamma + ar[916] =3D "Delta"; // Greek capital letter delta + ar[917] =3D "Epsilon"; // Greek capital letter epsilon + ar[918] =3D "Zeta"; // Greek capital letter zeta + ar[919] =3D "Eta"; // Greek capital letter eta + ar[920] =3D "Theta"; // Greek capital letter theta + ar[921] =3D "Iota"; // Greek capital letter iota + ar[922] =3D "Kappa"; // Greek capital letter kappa + ar[923] =3D "Lambda"; // Greek capital letter lambda + ar[924] =3D "Mu"; // Greek capital letter mu + ar[925] =3D "Nu"; // Greek capital letter nu + ar[926] =3D "Xi"; // Greek capital letter xi + ar[927] =3D "Omicron"; // Greek capital letter omicron + ar[928] =3D "Pi"; // Greek capital letter pi + ar[929] =3D "Rho"; // Greek capital letter rho + ar[931] =3D "Sigma"; // Greek capital letter sigma + ar[932] =3D "Tau"; // Greek capital letter tau + ar[933] =3D "Upsilon"; // Greek capital letter upsilon + ar[934] =3D "Phi"; // Greek capital letter phi + ar[935] =3D "Chi"; // Greek capital letter chi + ar[936] =3D "Psi"; // Greek capital letter psi + ar[937] =3D "Omega"; // Greek capital letter omega + ar[945] =3D "alpha"; // Greek small letter alpha + ar[946] =3D "beta"; // Greek small letter beta + ar[947] =3D "gamma"; // Greek small letter gamma + ar[948] =3D "delta"; // Greek small letter delta + ar[949] =3D "epsilon"; // Greek small letter epsilon + ar[950] =3D "zeta"; // Greek small letter zeta + ar[951] =3D "eta"; // Greek small letter eta + ar[952] =3D "theta"; // Greek small letter theta + ar[953] =3D "iota"; // Greek small letter iota + ar[954] =3D "kappa"; // Greek small letter kappa + ar[955] =3D "lambda"; // Greek small letter lambda + ar[956] =3D "mu"; // Greek small letter mu + ar[957] =3D "nu"; // Greek small letter nu + ar[958] =3D "xi"; // Greek small letter xi + ar[959] =3D "omicron"; // Greek small letter omicron + ar[960] =3D "pi"; // Greek small letter pi + ar[961] =3D "rho"; // Greek small letter rho + ar[962] =3D "sigmaf"; // Greek small letter final sigma + ar[963] =3D "sigma"; // Greek small letter sigma + ar[964] =3D "tau"; // Greek small letter tau + ar[965] =3D "upsilon"; // Greek small letter upsilon + ar[966] =3D "phi"; // Greek small letter phi + ar[967] =3D "chi"; // Greek small letter chi + ar[968] =3D "psi"; // Greek small letter psi + ar[969] =3D "omega"; // Greek small letter omega + ar[977] =3D "thetasym";// Greek theta symbol + ar[978] =3D "upsih"; // Greek upsilon with hook symbol + ar[982] =3D "piv"; // Greek pi symbol + ar[8194] =3D "ensp"; // en space + ar[8195] =3D "emsp"; // em space + ar[8201] =3D "thinsp"; // thin space + ar[8204] =3D "zwnj"; // zero width non-joiner + ar[8205] =3D "zwj"; // zero width joiner + ar[8206] =3D "lrm"; // left-to-right mark + ar[8207] =3D "rlm"; // right-to-left mark + ar[8211] =3D "ndash"; // en dash + ar[8212] =3D "mdash"; // em dash + ar[8216] =3D "lsquo"; // left single quotation mark + ar[8217] =3D "rsquo"; // right single quotation mark + ar[8218] =3D "sbquo"; // single low-9 quotation mark + ar[8220] =3D "ldquo"; // left double quotation mark + ar[8221] =3D "rdquo"; // right double quotation mark + ar[8222] =3D "bdquo"; // double low-9 quotation mark + ar[8224] =3D "dagger"; // dagger + ar[8225] =3D "Dagger"; // double dagger + ar[8226] =3D "bull"; // bullet + ar[8230] =3D "hellip"; // horizontal ellipsis + ar[8240] =3D "permil"; // per mille sign + ar[8242] =3D "prime"; // prime + ar[8243] =3D "Prime"; // double prime + ar[8249] =3D "lsaquo"; // single left-pointing angle quotation mark + ar[8250] =3D "rsaquo"; // single right-pointing angle quotation mark + ar[8254] =3D "oline"; // overline + ar[8260] =3D "frasl"; // fraction slash + ar[8364] =3D "euro"; // euro sign + ar[8465] =3D "image"; // black-letter capital i + ar[8472] =3D "weierp"; // script capital pXCOMMAX Weierstrass p + ar[8476] =3D "real"; // black-letter capital r + ar[8482] =3D "trade"; // trademark sign + ar[8501] =3D "alefsym";// alef symbol + ar[8592] =3D "larr"; // leftwards arrow + ar[8593] =3D "uarr"; // upwards arrow + ar[8594] =3D "rarr"; // rightwards arrow + ar[8595] =3D "darr"; // downwards arrow + ar[8596] =3D "harr"; // left right arrow + ar[8629] =3D "crarr"; // downwards arrow with corner leftwards + ar[8656] =3D "lArr"; // leftwards double arrow + ar[8657] =3D "uArr"; // upwards double arrow + ar[8658] =3D "rArr"; // rightwards double arrow + ar[8659] =3D "dArr"; // downwards double arrow + ar[8660] =3D "hArr"; // left right double arrow + ar[8704] =3D "forall"; // for all + ar[8706] =3D "part"; // partial differential + ar[8707] =3D "exist"; // there exists + ar[8709] =3D "empty"; // empty set + ar[8711] =3D "nabla"; // nabla + ar[8712] =3D "isin"; // element of + ar[8713] =3D "notin"; // not an element of + ar[8715] =3D "ni"; // contains as member + ar[8719] =3D "prod"; // n-ary product + ar[8721] =3D "sum"; // n-ary summation + ar[8722] =3D "minus"; // minus sign + ar[8727] =3D "lowast"; // asterisk operator + ar[8730] =3D "radic"; // square root + ar[8733] =3D "prop"; // proportional to + ar[8734] =3D "infin"; // infinity + ar[8736] =3D "ang"; // angle + ar[8743] =3D "and"; // logical and + ar[8744] =3D "or"; // logical or + ar[8745] =3D "cap"; // intersection + ar[8746] =3D "cup"; // union + ar[8747] =3D "int"; // integral + ar[8756] =3D "there4"; // therefore + ar[8764] =3D "sim"; // tilde operator + ar[8773] =3D "cong"; // congruent to + ar[8776] =3D "asymp"; // almost equal to + ar[8800] =3D "ne"; // not equal to + ar[8801] =3D "equiv"; // identical toXCOMMAX equivalent to + ar[8804] =3D "le"; // less-than or equal to + ar[8805] =3D "ge"; // greater-than or equal to + ar[8834] =3D "sub"; // subset of + ar[8835] =3D "sup"; // superset of + ar[8836] =3D "nsub"; // not a subset of + ar[8838] =3D "sube"; // subset of or equal to + ar[8839] =3D "supe"; // superset of or equal to + ar[8853] =3D "oplus"; // circled plus + ar[8855] =3D "otimes"; // circled times + ar[8869] =3D "perp"; // up tack + ar[8901] =3D "sdot"; // dot operator + ar[8968] =3D "lceil"; // left ceiling + ar[8969] =3D "rceil"; // right ceiling + ar[8970] =3D "lfloor"; // left floor + ar[8971] =3D "rfloor"; // right floor + ar[9001] =3D "lang"; // left-pointing angle bracket + ar[9002] =3D "rang"; // right-pointing angle bracket + ar[9674] =3D "loz"; // lozenge + ar[9824] =3D "spades"; // black spade suit + ar[9827] =3D "clubs"; // black club suit + ar[9829] =3D "hearts"; // black heart suit + ar[9830] =3D "diams"; // black diamond suit + = + return ar; + } + = + /** + * Build an array to store the hex string for characters to be encoded. + * If the character shouldn't be encoded, then store null. + * = + * @return An array containing characters in hex string that are to be = encoded. + */ + private String[] buildHexEntityNumberArray() + { + String[] array =3D new String[256]; + = + /* + * Initialize an array to mark which characters are to be encoded. S= tore the hex + * string for that character to save time later. If the character sh= ouldn't be + * encoded, then store null. + */ + for (char c =3D 0; c < 0xFF; c++) + { + if (c >=3D 0x30 && c <=3D 0x39 || c >=3D 0x41 && c <=3D 0x5A || c= >=3D 0x61 && c <=3D 0x7A) + { + array[c] =3D null; + } + else + { + array[c] =3D Integer.toHexString(c); + } + } + = + return array; + } +} Added: portal/branches/xss/component/common/src/test/java/org/exoplatform/c= ommons/utils/TestHTMLEntityEncoder.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- portal/branches/xss/component/common/src/test/java/org/exoplatform/comm= ons/utils/TestHTMLEntityEncoder.java (rev 0) +++ portal/branches/xss/component/common/src/test/java/org/exoplatform/comm= ons/utils/TestHTMLEntityEncoder.java 2011-09-29 08:08:23 UTC (rev 7556) @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2011 eXo Platform SAS. + * = + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * = + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * = + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.exoplatform.commons.utils; + +import junit.framework.TestCase; + +/** + * @author Trong Tran + * @version $Revision$ + */ +public class TestHTMLEntityEncoder extends TestCase +{ + private HTMLEntityEncoder htmlEncoder =3D HTMLEntityEncoder.getInstance= (); + + public void testHTMLEncoding() + { + assertEquals("<h1>HELLO WORLD</h1>", htmlEncoder.en= codeHTML("

HELLO WORLD

")); + = + assertEquals("alert('HELLO WORLD')", htmlEncoder= .encodeHTML("alert('HELLO WORLD')")); + + assertEquals( + "<a href="http://example.com/&#x= 3f;name1=value1&name2=value2&name3=a+b">= ;link</a>", + htmlEncoder.encodeHTML("link")); + } + = + public void testHTMLAttributeEncoding() + { + assertEquals("<h1>HELLO WORLD</h1>", htmlEncod= er.encodeHTMLAttribute("

HELLO WORLD

")); + = + assertEquals("alert('HELLO WORLD')", htmlEn= coder.encodeHTMLAttribute("alert('HELLO WORLD')")); + = + assertEquals( + "<a href="http://example.com= f;?name1=value1&name2=value2&name3=a+b&quo= t;>link</a>", + htmlEncoder.encodeHTMLAttribute("link")); + } +} --===============2620492953244463295==--