Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/main/java/org/apache/commons/lang3/ClassUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/org/apache/commons/lang3/ClassUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading