You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by pa...@apache.org on 2017/10/07 09:55:08 UTC
[1/2] [lang] LANG-1348 - StackOverflowError on
TypeUtils.toString(...) for a generic return type of Enum.valueOf (closes
#292)
Repository: commons-lang
Updated Branches:
refs/heads/master 36217ee16 -> 00feb98f8
LANG-1348 - StackOverflowError on TypeUtils.toString(...) for a generic return type of Enum.valueOf (closes #292)
Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/cc6beb2d
Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/cc6beb2d
Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/cc6beb2d
Branch: refs/heads/master
Commit: cc6beb2d05347fba64d933906ae2b712b1a43302
Parents: 36217ee
Author: mbusso <ma...@gmail.com>
Authored: Thu Sep 28 21:51:24 2017 -0300
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sat Oct 7 11:50:15 2017 +0200
----------------------------------------------------------------------
.../apache/commons/lang3/reflect/TypeUtils.java | 46 ++++++++++++++++++--
.../commons/lang3/reflect/TypeUtilsTest.java | 6 +++
2 files changed, 49 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/cc6beb2d/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
index 54c810d..9e07c33 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
@@ -1788,7 +1788,7 @@ public class TypeUtils {
final Type useOwner = p.getOwnerType();
final Class<?> raw = (Class<?>) p.getRawType();
- final Type[] typeArguments = p.getActualTypeArguments();
+
if (useOwner == null) {
buf.append(raw.getName());
} else {
@@ -1800,10 +1800,46 @@ public class TypeUtils {
buf.append('.').append(raw.getSimpleName());
}
- appendAllTo(buf.append('<'), ", ", typeArguments).append('>');
+ final int[] recursiveTypeIndexes = findRecursiveTypes(p);
+
+ if (recursiveTypeIndexes.length > 0) {
+ appendRecursiveTypes(buf, recursiveTypeIndexes, p.getActualTypeArguments());
+ } else {
+ appendAllTo(buf.append('<'), ", ", p.getActualTypeArguments()).append('>');
+ }
+
return buf.toString();
}
+ private static void appendRecursiveTypes(StringBuilder buf, int[] recursiveTypeIndexes, Type[] argumentTypes) {
+ for (int i = 0; i < recursiveTypeIndexes.length; i++) {
+ appendAllTo(buf.append('<'), ", ", argumentTypes[i].toString()).append('>');
+ }
+
+ final Type[] argumentsFiltered = ArrayUtils.removeAll(argumentTypes, recursiveTypeIndexes);
+
+ if (argumentsFiltered.length > 0) {
+ appendAllTo(buf.append('<'), ", ", argumentsFiltered).append('>');
+ }
+ }
+
+ private static int[] findRecursiveTypes(ParameterizedType p) {
+ Type[] filteredArgumentTypes = Arrays.copyOf(p.getActualTypeArguments(), p.getActualTypeArguments().length);
+ int[] indexesToRemove = new int[] {};
+ for (int i = 0; i < filteredArgumentTypes.length; i++) {
+ if (filteredArgumentTypes[i] instanceof TypeVariable<?>) {
+ if (containsVariableTypeSameParametrizedTypeBound(((TypeVariable<?>) filteredArgumentTypes[i]), p)) {
+ indexesToRemove = ArrayUtils.add(indexesToRemove, i);
+ }
+ }
+ }
+ return indexesToRemove;
+ }
+
+ private static boolean containsVariableTypeSameParametrizedTypeBound(TypeVariable<?> typeVariable, ParameterizedType p) {
+ return ArrayUtils.contains(typeVariable.getBounds(), p);
+ }
+
/**
* Format a {@link WildcardType} as a {@link String}.
* @param w {@code WildcardType} to format
@@ -1840,7 +1876,7 @@ public class TypeUtils {
* @return {@code buf}
* @since 3.2
*/
- private static StringBuilder appendAllTo(final StringBuilder buf, final String sep, final Type... types) {
+ private static <T> StringBuilder appendAllTo(final StringBuilder buf, final String sep, final T... types) {
Validate.notEmpty(Validate.noNullElements(types));
if (types.length > 0) {
buf.append(toString(types[0]));
@@ -1851,4 +1887,8 @@ public class TypeUtils {
return buf;
}
+ private static <T> String toString(T object) {
+ return object instanceof Type ? toString((Type) object) : object.toString();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/cc6beb2d/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java b/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
index 1b88147..eea6b87 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
@@ -781,6 +781,12 @@ public class TypeUtilsTest<B> {
Assert.assertTrue(TypeUtils.isAssignable(fromType, failingToType));
}
+ @Test
+ public void testLANG1348() throws Exception {
+ final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
+ Assert.assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
+ }
+
public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
public static <G extends Comparable<G>> G stub() {
[2/2] [lang] LANG-1348: StackOverflowError on TypeUtils.toString(...)
for a generic return type of Enum.valueOf
Posted by pa...@apache.org.
LANG-1348: StackOverflowError on TypeUtils.toString(...) for a generic return type of Enum.valueOf
add changes.xml entry
Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/00feb98f
Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/00feb98f
Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/00feb98f
Branch: refs/heads/master
Commit: 00feb98f807cf44c993296052726043a90d70b7e
Parents: cc6beb2
Author: pascalschumacher <pa...@gmx.net>
Authored: Sat Oct 7 11:54:38 2017 +0200
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sat Oct 7 11:54:38 2017 +0200
----------------------------------------------------------------------
src/changes/changes.xml | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-lang/blob/00feb98f/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ec74e49..187b5f0 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,6 +46,7 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="3.7" date="tba" description="tba">
+ <action issue="LANG-1348" type="fix" dev="pschumacher" due-to="mbusso">StackOverflowError on TypeUtils.toString(...) for a generic return type of Enum.valueOf</action>
<action issue="LANG-1346" type="update" dev="pschumacher">Remove deprecation from RandomStringUtils</action>
<action issue="LANG-1350" type="fix" dev="ggregory" due-to="Brett Kail">ConstructorUtils.invokeConstructor(Class, Object...) regression</action>
<action issue="LANG-1349" type="fix" dev="pschumacher" due-to="Naman Nigam">EqualsBuilder#isRegistered: swappedPair construction bug</action>