This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git

commit a5f9a0cc22e4626234a4d7b53bf357d61eb2478b
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Thu May 1 12:37:40 2025 -0400

    org.apache.commons.lang3.ClassUtils.getCanonicalName(String) now throws
    an IllegalArgumentException for array dimensions greater than 255
    
    - No need to create strings over and over in a loop
    - Preallocate string builder
    - Javadoc since tag not needed for a private method
---
 src/changes/changes.xml                              |  1 +
 .../java/org/apache/commons/lang3/ClassUtils.java    | 20 ++++++++++++++------
 .../org/apache/commons/lang3/ClassUtilsTest.java     |  4 ++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 411dc47c2..289725383 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -87,6 +87,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Reimplement StringUtils.toCodePoints(CharSequence) to use 
java.lang.CharSequence.codePoints().</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Reimplement StringUtils.capitalize(String) to use 
java.lang.CharSequence.codePoints().</action>
     <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">Reimplement StringUtils.uncapitalize(String) to use 
java.lang.CharSequence.codePoints().</action>
+    <action                   type="fix" dev="ggregory" due-to="Gary 
Gregory">org.apache.commons.lang3.ClassUtils.getCanonicalName(String) now 
throws an IllegalArgumentException for array dimensions greater than 
255.</action>
     <action                   type="fix" dev="ggregory" due-to="Sridhar 
Balijepalli, Piotr P. Karwasz">Fix Javadoc typo and improve clarity in 
defaultIfBlank method #1376.</action>
     <!-- ADD -->
     <action                   type="add" dev="ggregory" due-to="Gary 
Gregory">Add Strings and refactor StringUtils.</action>
diff --git a/src/main/java/org/apache/commons/lang3/ClassUtils.java 
b/src/main/java/org/apache/commons/lang3/ClassUtils.java
index 1853da22e..61c0a5125 100644
--- a/src/main/java/org/apache/commons/lang3/ClassUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ClassUtils.java
@@ -50,6 +50,11 @@
  */
 public class ClassUtils {
 
+    /**
+     * The maximum number of array dimensions.
+     */
+    private static final int MAX_DIMENSIONS = 255;
+
     /**
      * Inclusivity literals for {@link #hierarchy(Class, Interfaces)}.
      *
@@ -470,9 +475,8 @@ public static String getCanonicalName(final Object object, 
final String valueIfN
      * </ul>
      * </p>
      *
-     * @param className the name of class
-     * @return canonical form of class name
-     * @since 2.4
+     * @param className the name of class.
+     * @return canonical form of class name.
      */
     private static String getCanonicalName(final String name) {
         String className = StringUtils.deleteWhitespace(name);
@@ -480,19 +484,23 @@ private static String getCanonicalName(final String name) 
{
             return null;
         }
         int dim = 0;
-        while (className.startsWith("[")) {
+        while (className.charAt(dim) == '[') {
             dim++;
-            className = className.substring(1);
+            if (dim > MAX_DIMENSIONS) {
+                throw new IllegalArgumentException(String.format("Maximum 
array dimension %d exceeded", MAX_DIMENSIONS));
+            }
         }
         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 = reverseAbbreviationMap.get(className.substring(0, 1));
         }
-        final StringBuilder canonicalClassNameBuffer = new 
StringBuilder(className);
+        final StringBuilder canonicalClassNameBuffer = new 
StringBuilder(className.length() + dim * 2);
+        canonicalClassNameBuffer.append(className);
         for (int i = 0; i < dim; i++) {
             canonicalClassNameBuffer.append("[]");
         }
diff --git a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
index 0786bdbca..1aa4188e0 100644
--- a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
@@ -562,13 +562,13 @@ public void test_getShortCanonicalName_String() {
         assertEquals("int[][]", ClassUtils.getShortCanonicalName("[[I"));
         assertEquals("int[]", ClassUtils.getShortCanonicalName("int[]"));
         assertEquals("int[][]", ClassUtils.getShortCanonicalName("int[][]"));
-
         // this is to demonstrate that the documentation and the naming of the 
methods
         // uses the class name and canonical name totally mixed up, which 
cannot be
         // fixed without backward compatibility break
         assertEquals("int[]", int[].class.getCanonicalName());
         assertEquals("[I", int[].class.getName());
-
+        assertThrows(IllegalArgumentException.class, () -> 
ClassUtils.getShortCanonicalName(StringUtils.repeat("[", 256) + "I"));
+        assertEquals("int" + StringUtils.repeat("[]", 255), 
ClassUtils.getShortCanonicalName(StringUtils.repeat("[", 255) + "I"));
         // Inner types... the problem is that these are not canonical names, 
classes with this name do not even have canonical
         // name
         // WARNING: this is fragile, implementation may change, naming is not 
guaranteed

Reply via email to