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

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


The following commit(s) were added to refs/heads/master by this push:
     new 28f46460d ClassUtils.toCleanName(String) resolves malformed array 
suffixes instead (#1670)
28f46460d is described below

commit 28f46460d63b4c7806a2b9cce382b2b79ba6fd50
Author: Gary Gregory <[email protected]>
AuthorDate: Sun May 24 09:32:23 2026 -0400

    ClassUtils.toCleanName(String) resolves malformed array suffixes instead 
(#1670)
    
    of throwing
    
    Called by ClassUtils.getClass(ClassLoader, String, boolean)
---
 .../java/org/apache/commons/lang3/ClassUtils.java  |  7 ++++++
 .../org/apache/commons/lang3/ClassUtilsTest.java   | 28 ++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/src/main/java/org/apache/commons/lang3/ClassUtils.java 
b/src/main/java/org/apache/commons/lang3/ClassUtils.java
index 1e7a3b5e3..c0ce2a726 100644
--- a/src/main/java/org/apache/commons/lang3/ClassUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ClassUtils.java
@@ -1643,6 +1643,13 @@ private static String toCleanName(final String 
className) {
             throw new IllegalArgumentException(String.format("Class name 
greater than maxium length %,d", MAX_CLASS_NAME_LENGTH));
         }
         if (canonicalName.endsWith(arrayMarker)) {
+            // Reject malformed inputs like "java.lang.String[]junk[]" or
+            // "java.lang.String[]][]" where the suffix is not composed of
+            // repeated "[]" pairs.
+            final String tail = canonicalName.substring(arrIdx);
+            if (!tail.matches("(?:\\[\\])+")) {
+                throw new IllegalArgumentException("Malformed array name: " + 
canonicalName);
+            }
             final int dims =  (canonicalName.length() - arrIdx) / 2;
             if (dims > MAX_JVM_ARRAY_DIMENSION) {
                 throw new IllegalArgumentException("Array dimension greater 
than JVM specification maximum of 255.");
diff --git a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
index 200e814e5..8f18a2bc8 100644
--- a/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
@@ -1320,6 +1320,34 @@ void testGetClassRawPrimitives() throws 
ClassNotFoundException {
         assertEquals(void.class, ClassUtils.getClass("void"));
     }
 
+    /**
+     * Pre-patch: getClass("java.lang.String[]junk[]") silently returns 
String[][][][] (4 dims, because (24 - 16)/2 = 4 — junk is 4 chars). Post-patch: 
must
+     * throw IllegalArgumentException.
+     */
+    @Test
+    public void testGetClassStringMalformedMiddleJunkRejected() {
+        assertThrows(IllegalArgumentException.class, () -> 
ClassUtils.getClass("java.lang.String[]junk[]"));
+    }
+
+    /**
+     * Mutation control: suffix ends with "[]" so the array-branch is entered, 
and the suffix from arrIdx contains only '[' and ']' chars but NOT as 
well-formed
+     * pairs ("[]][]"). A char-class-only patch would accept this; the correct 
pair-validating patch must reject. Without this case, a weaker patch would still
+     * pass.
+     */
+    @Test
+    public void testGetClassStringMalformedUnpairedBracketsRejected() {
+        assertThrows(IllegalArgumentException.class, () -> 
ClassUtils.getClass("java.lang.String[]][]"));
+    }
+
+    /**
+     * Negative control: well-formed multi-dim array still resolves. Confirms 
the fix is minimal and does not over-reject.
+     */
+    @Test
+    public void testGetClassStringWellFormedArrayStillResolves() throws 
Exception {
+        assertNotNull(ClassUtils.getClass("java.lang.String[]"));
+        assertNotNull(ClassUtils.getClass("java.lang.String[][]"));
+    }
+
     @Test
     void testGetClassWithArrayClasses() throws Exception {
         assertGetClassReturnsClass(String[].class);

Reply via email to