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