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);