Merge branch 'master' of https://garydgregory@github.com/apache/commons-lang.git
diff --git a/src/main/java/org/apache/commons/lang3/ClassUtils.java b/src/main/java/org/apache/commons/lang3/ClassUtils.java
index dc591bf..d2a36f2 100644
--- a/src/main/java/org/apache/commons/lang3/ClassUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ClassUtils.java
@@ -471,6 +471,7 @@ public static String getCanonicalName(final Object object, final String valueIfN
      *
      * @param name the name of class.
      * @return canonical form of class name.
+     * @throws IllegalArgumentException if the class name is invalid
      */
     private static String getCanonicalName(final String name) {
         String className = StringUtils.deleteWhitespace(name);
@@ -478,20 +479,33 @@ private static String getCanonicalName(final String name) {
             return null;
         }
         int dim = 0;
-        while (className.charAt(dim) == '[') {
+        final int len = className.length();
+        while (dim < len && className.charAt(dim) == '[') {
             dim++;
             if (dim > MAX_DIMENSIONS) {
                 throw new IllegalArgumentException(String.format("Maximum array dimension %d exceeded", MAX_DIMENSIONS));
             }
         }
+        if (dim >= len) {
+            throw new IllegalArgumentException(String.format("Invalid class name %s", name));
+        }
         if (dim < 1) {
             return className;
         }
         className = className.substring(dim);
         if (className.startsWith("L")) {
-            className = className.substring(1, className.endsWith(";") ? className.length() - 1 : className.length());
-        } else if (!className.isEmpty()) {
-            className = REVERSE_ABBREVIATION_MAP.get(className.substring(0, 1));
+            if (!className.endsWith(";") || className.length() < 3) {
+                throw new IllegalArgumentException(String.format("Invalid class name %s", name));
+            }
+            className = className.substring(1, className.length() - 1);
+        } else if (className.length() == 1) {
+            final String primitive = REVERSE_ABBREVIATION_MAP.get(className.substring(0, 1));
+            if (primitive == null) {
+                throw new IllegalArgumentException(String.format("Invalid class name %s", name));
+            }
+            className = primitive;
+        } else {
+            throw new IllegalArgumentException(String.format("Invalid class name %s", name));
         }
         final StringBuilder canonicalClassNameBuffer = new StringBuilder(className.length() + dim * 2);
         canonicalClassNameBuffer.append(className);
diff --git a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
index 1f7bdd8..3203911 100644
--- a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
@@ -592,15 +592,19 @@ void test_getShortCanonicalName_String() {
         assertEquals("String[]", ClassUtils.getShortCanonicalName(String[].class.getName()));
         assertEquals("String[]", ClassUtils.getShortCanonicalName(String[].class.getCanonicalName()));
         assertEquals("String[]", ClassUtils.getShortCanonicalName("String[]"));
-        // Note that we throw RuntimeException (but not which one) for the following bad inputs:
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName(""));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("["));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("[]"));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("[;"));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("[];"));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName(" "));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("[$"));
-        assertThrows(RuntimeException.class, () -> ClassUtils.getShortCanonicalName("[$a"));
+        // Note that we throw IllegalArgumentException for the following bad inputs:
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName(""));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("["));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[]"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[;"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[];"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName(" "));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[$"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[$a"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[["));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[[L"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[org.apache.commons.lang3.ClassUtilsTest"));
+        assertThrows(IllegalArgumentException.class, () -> ClassUtils.getShortCanonicalName("[Lorg.apache.commons.lang3.ClassUtilsTest"));
     }
 
     @Test