You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2025/05/01 16:37:49 UTC
(commons-lang) 03/03: org.apache.commons.lang3.ClassUtils.getCanonicalName(String) now throws an IllegalArgumentException for array dimensions greater than 255
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 <ga...@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