Permalink
Browse files

Improve the handling of methods with varargs in EL expressions. In pa…

…rticular, the calling of a varargs method with no parameters now works correctly.

Based on a patch by Nitkalya (Ing) Wiriyanuparb.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1817495 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
markt-asf committed Dec 8, 2017
1 parent ff00d70 commit b7ce5679b9e6a073dadbc31e6ecde12ad1e0ede8
View
@@ -38,6 +38,7 @@
class Util {
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
/**
* Checks whether the supplied Throwable is one that needs to be
@@ -237,11 +238,29 @@ private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers,
}
// Check the number of parameters
if (!(paramCount == mParamCount ||
(w.isVarArgs() && paramCount >= mParamCount))) {
// Multiple tests to improve readability
if (!w.isVarArgs() && paramCount != mParamCount) {
// Method has wrong number of parameters
continue;
}
if (w.isVarArgs() && paramCount < mParamCount -1) {
// Method has wrong number of parameters
continue;
}
if (w.isVarArgs() && paramCount == mParamCount && paramValues != null &&
paramValues.length > paramCount && !paramTypes[mParamCount -1].isArray()) {
// Method arguments don't match
continue;
}
if (w.isVarArgs() && paramCount > mParamCount && paramValues != null &&
paramValues.length != paramCount) {
// Number of parameter types and values do not agree
throw new IllegalArgumentException();
}
if (!w.isVarArgs() && paramValues != null && paramCount != paramValues.length) {
// Number of parameter types and values do not agree
throw new IllegalArgumentException();
}
// Check the parameters match
int exactMatch = 0;
@@ -250,9 +269,12 @@ private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers,
boolean noMatch = false;
for (int i = 0; i < mParamCount; i++) {
// Can't be null
if (mParamTypes[i].equals(paramTypes[i])) {
exactMatch++;
} else if (i == (mParamCount - 1) && w.isVarArgs()) {
if (w.isVarArgs() && i == (mParamCount - 1)) {
if (i == paramCount && paramCount == (mParamCount - 1)) {
// Nothing is passed as varargs
assignableMatch++;
break;
}
Class<?> varType = mParamTypes[i].getComponentType();
for (int j = i; j < paramCount; j++) {
if (isAssignableFrom(paramTypes[j], varType)) {
@@ -274,18 +296,22 @@ private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers,
// lead to a varArgs method matching when the result
// should be ambiguous
}
} else if (isAssignableFrom(paramTypes[i], mParamTypes[i])) {
assignableMatch++;
} else {
if (paramValues == null) {
noMatch = true;
break;
if (mParamTypes[i].equals(paramTypes[i])) {
exactMatch++;
} else if (paramTypes[i] != null && isAssignableFrom(paramTypes[i], mParamTypes[i])) {
assignableMatch++;
} else {
if (isCoercibleFrom(paramValues[i], mParamTypes[i])) {
coercibleMatch++;
} else {
if (paramValues == null) {
noMatch = true;
break;
} else {
if (isCoercibleFrom(paramValues[i], mParamTypes[i])) {
coercibleMatch++;
} else {
noMatch = true;
break;
}
}
}
}
@@ -595,7 +621,11 @@ static Method getMethod(Class<?> type, Method m) {
Object[] parameters = null;
if (parameterTypes.length > 0) {
parameters = new Object[parameterTypes.length];
int paramCount = params.length;
int paramCount;
if (params == null) {
params = EMPTY_OBJECT_ARRAY;
}
paramCount = params.length;
if (isVarArgs) {
int varArgIndex = parameterTypes.length - 1;
// First argCount-1 parameters are standard
@@ -129,6 +129,7 @@ private ReflectionUtil() {
public static Method getMethod(EvaluationContext ctx, Object base, Object property,
Class<?>[] paramTypes, Object[] paramValues)
throws MethodNotFoundException {
if (base == null || property == null) {
throw new MethodNotFoundException(MessageFactory.get(
"error.method.notfound", base, property,
@@ -163,11 +164,29 @@ public static Method getMethod(EvaluationContext ctx, Object base, Object proper
}
// Check the number of parameters
if (!(paramCount == mParamCount ||
(m.isVarArgs() && paramCount >= mParamCount))) {
// Multiple tests to improve readability
if (!m.isVarArgs() && paramCount != mParamCount) {
// Method has wrong number of parameters
continue;
}
if (m.isVarArgs() && paramCount < mParamCount -1) {
// Method has wrong number of parameters
continue;
}
if (m.isVarArgs() && paramCount == mParamCount && paramValues != null &&
paramValues.length > paramCount && !paramTypes[mParamCount -1].isArray()) {
// Method arguments don't match
continue;
}
if (m.isVarArgs() && paramCount > mParamCount && paramValues != null &&
paramValues.length != paramCount) {
// Number of parameter types and values do not agree
throw new IllegalArgumentException();
}
if (!m.isVarArgs() && paramValues != null && paramCount != paramValues.length) {
// Number of parameter types and values do not agree
throw new IllegalArgumentException();
}
// Check the parameters match
int exactMatch = 0;
@@ -176,15 +195,18 @@ public static Method getMethod(EvaluationContext ctx, Object base, Object proper
boolean noMatch = false;
for (int i = 0; i < mParamCount; i++) {
// Can't be null
if (mParamTypes[i].equals(paramTypes[i])) {
exactMatch++;
} else if (i == (mParamCount - 1) && m.isVarArgs()) {
if (m.isVarArgs() && i == (mParamCount - 1)) {
if (i == paramCount && paramCount == (mParamCount - 1)) {
// Nothing is passed as varargs
assignableMatch++;
break;
}
Class<?> varType = mParamTypes[i].getComponentType();
for (int j = i; j < paramCount; j++) {
if (isAssignableFrom(paramTypes[j], varType)) {
assignableMatch++;
} else {
if (paramValues == null || j >= paramValues.length) {
if (paramValues == null) {
noMatch = true;
break;
} else {
@@ -200,18 +222,22 @@ public static Method getMethod(EvaluationContext ctx, Object base, Object proper
// lead to a varArgs method matching when the result
// should be ambiguous
}
} else if (isAssignableFrom(paramTypes[i], mParamTypes[i])) {
assignableMatch++;
} else {
if (paramValues == null || i >= paramValues.length) {
noMatch = true;
break;
if (mParamTypes[i].equals(paramTypes[i])) {
exactMatch++;
} else if (paramTypes[i] != null && isAssignableFrom(paramTypes[i], mParamTypes[i])) {
assignableMatch++;
} else {
if (isCoercibleFrom(ctx, paramValues[i], mParamTypes[i])) {
coercibleMatch++;
} else {
if (paramValues == null) {
noMatch = true;
break;
} else {
if (isCoercibleFrom(ctx, paramValues[i], mParamTypes[i])) {
coercibleMatch++;
} else {
noMatch = true;
break;
}
}
}
}
@@ -527,5 +553,4 @@ public int hashCode()
;
}
}
}
Oops, something went wrong.

0 comments on commit b7ce567

Please sign in to comment.