This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push:
new 5dede14ab reject varargs candidates with too few arguments in
MemberUtils (#1828)
5dede14ab is described below
commit 5dede14ab1e385b6d972b8bcb4f1f0f941e59db2
Author: alhuda <[email protected]>
AuthorDate: Tue Oct 20 02:00:08 2026 +0530
reject varargs candidates with too few arguments in MemberUtils (#1828)
isMatchingExecutable accepted a varargs method or constructor without
checking that enough arguments were supplied for its fixed parameters,
so getMatchingAccessibleMethod and getMatchingAccessibleConstructor
returned inapplicable members and invokeMethod, invokeStaticMethod and
invokeConstructor failed with ArrayIndexOutOfBoundsException from
toVarArgs instead of NoSuchMethodException.
---
.../java/org/apache/commons/lang3/reflect/MemberUtils.java | 2 +-
.../apache/commons/lang3/reflect/ConstructorUtilsTest.java | 13 +++++++++++++
.../org/apache/commons/lang3/reflect/MethodUtilsTest.java | 6 ++++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/apache/commons/lang3/reflect/MemberUtils.java
b/src/main/java/org/apache/commons/lang3/reflect/MemberUtils.java
index 7be7e2b48..1094190fd 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/MemberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/MemberUtils.java
@@ -252,7 +252,7 @@ private static boolean isMatchingExecutable(final
Executable method, final Class
if (ClassUtils.isAssignable(parameterTypes, methodParameterTypes,
true)) {
return true;
}
- if (method.isVarArgs()) {
+ if (method.isVarArgs() && parameterTypes.length >=
methodParameterTypes.length - 1) {
int i;
for (i = 0; i < methodParameterTypes.length - 1 && i <
parameterTypes.length; i++) {
if (!ClassUtils.isAssignable(parameterTypes[i],
methodParameterTypes[i], true)) {
diff --git
a/src/test/java/org/apache/commons/lang3/reflect/ConstructorUtilsTest.java
b/src/test/java/org/apache/commons/lang3/reflect/ConstructorUtilsTest.java
index 93c52313a..b8c81ddfd 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/ConstructorUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/ConstructorUtilsTest.java
@@ -143,6 +143,13 @@ void verify(final String str, final String[] args) {
}
}
+ public static class VarArgsBean {
+
+ public VarArgsBean(final String first, final String... rest) {
+ // empty
+ }
+ }
+
private final Map<Class<?>, Class<?>[]> classCache;
public ConstructorUtilsTest() {
@@ -246,6 +253,12 @@ void testInvokeConstructorOnNonPublicClass() {
assertThrows(NoSuchMethodException.class, () ->
ConstructorUtils.invokeConstructor(PrivateClass.PublicInnerClass.class));
}
+ @Test
+ void testInvokeConstructorVarArgsTooFewArguments() {
+
assertNull(ConstructorUtils.getMatchingAccessibleConstructor(VarArgsBean.class));
+ assertThrows(NoSuchMethodException.class, () ->
ConstructorUtils.invokeConstructor(VarArgsBean.class));
+ }
+
@Test
void testInvokeExactConstructor() throws Exception {
assertEquals("()",
ConstructorUtils.invokeExactConstructor(TestBean.class, (Object[])
ArrayUtils.EMPTY_CLASS_ARRAY).toString());
diff --git
a/src/test/java/org/apache/commons/lang3/reflect/MethodUtilsTest.java
b/src/test/java/org/apache/commons/lang3/reflect/MethodUtilsTest.java
index 405c73191..947145999 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/MethodUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/MethodUtilsTest.java
@@ -1168,6 +1168,9 @@ void testInvokeMethod1PlusVarArgs() throws Exception {
assertEquals("int, int...", MethodUtils.invokeMethod(testBean,
"intIntVarArg", 1, 2));
assertEquals("int, int...", MethodUtils.invokeMethod(testBean,
"intIntVarArg", 1, 2, 3));
assertThrows(NoSuchMethodException.class, () ->
MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, "s1", 5));
+ // too few arguments for the fixed parameters
+ assertThrows(NoSuchMethodException.class, () ->
MethodUtils.invokeMethod(testBean, "intStringVarArg"));
+ assertNull(MethodUtils.getMatchingAccessibleMethod(TestBean.class,
"intStringVarArg"));
}
@Test
@@ -1346,6 +1349,9 @@ void testInvokeStaticMethod1PlusVarArgs() throws
Exception {
assertEquals("static int, int...", MethodUtils.invokeMethod(testBean,
"staticIntIntVarArg", 1, 2));
assertEquals("static int, int...", MethodUtils.invokeMethod(testBean,
"staticIntIntVarArg", 1, 2, 3));
assertThrows(NoSuchMethodException.class, () ->
MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, "s1", 5));
+ // too few arguments for the fixed parameters
+ assertThrows(NoSuchMethodException.class, () ->
MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg"));
+ assertThrows(NoSuchMethodException.class, () ->
MethodUtils.invokeStaticMethod(String.class, "format"));
}
@Test