PR: 25227
Obtained from: Discussion around http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25227


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137746 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/commons/lang/Entities.java b/src/java/org/apache/commons/lang/Entities.java
index e2f21a8..f769e6b 100644
--- a/src/java/org/apache/commons/lang/Entities.java
+++ b/src/java/org/apache/commons/lang/Entities.java
@@ -69,7 +69,7 @@
  * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
  * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
  * @since 2.0
- * @version $Id: Entities.java,v 1.15 2003/09/13 03:11:29 psteitz Exp $
+ * @version $Id: Entities.java,v 1.16 2004/01/10 02:58:36 ggregory Exp $
  */
 class Entities {
 
@@ -687,7 +687,12 @@
                 String entityName = str.substring(i + 1, semi);
                 int entityValue;
                 if (entityName.charAt(0) == '#') {
-                    entityValue = Integer.parseInt(entityName.substring(1));
+                    char charAt1 = entityName.charAt(1);
+                    if (charAt1 == 'x' || charAt1=='X') {
+                        entityValue = Integer.valueOf(entityName.substring(2), 16).intValue();
+                    } else {
+                        entityValue = Integer.parseInt(entityName.substring(1));
+                    }
                 } else {
                     entityValue = this.entityValue(entityName);
                 }
diff --git a/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java b/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
index f2c221a..5c37e53 100644
--- a/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
+++ b/src/test/org/apache/commons/lang/StringEscapeUtilsTest.java
@@ -67,7 +67,7 @@
  *
  * @author of original StringUtilsTest.testEscape = ?
  * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
- * @version $Id: StringEscapeUtilsTest.java,v 1.12 2003/08/18 02:22:25 bayard Exp $
+ * @version $Id: StringEscapeUtilsTest.java,v 1.13 2004/01/10 02:58:36 ggregory Exp $
  */
 public class StringEscapeUtilsTest extends TestCase {
     private final static String FOO = "foo";
@@ -262,10 +262,25 @@
         }
         // \u00E7 is a cedilla (c with wiggle under)
         // note that the test string must be 7-bit-clean (unicode escaped) or else it will compile incorrectly
-        // on some locales
+        // on some locales        
         assertEquals("funny chars pass through OK", "Fran\u00E7ais", StringEscapeUtils.unescapeHtml("Fran\u00E7ais"));
     }
 
+    public void testUnescapeHexCharsHtml() {
+        // Simple easy to grok test 
+        assertEquals("hex number unescape", "\u0080\u009F", StringEscapeUtils.unescapeHtml("&#x80;&#x9F;"));
+        assertEquals("hex number unescape", "\u0080\u009F", StringEscapeUtils.unescapeHtml("&#X80;&#X9F;"));
+        // Test all Character values:
+        for (char i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++) {
+            Character c1 = new Character(i);
+            Character c2 = new Character((char)(i+1));
+            String expected = c1.toString() + c2.toString();
+            String escapedC1 = "&#x" + Integer.toHexString((int)(c1.charValue())) + ";";
+            String escapedC2 = "&#x" + Integer.toHexString((int)(c2.charValue())) + ";";
+            assertEquals("hex number unescape index " + (int)i, expected, StringEscapeUtils.unescapeHtml(escapedC1 + escapedC2));
+        }
+    }
+
     public void testUnescapeUnknownEntity() throws Exception
     {
         assertEquals("&zzzz;", StringEscapeUtils.unescapeHtml("&zzzz;"));