Ensure varargs component type for MethodHandle is not null in SpEL

This commit ensures that the varargs component type for a MethodHandle
cannot be null in ReflectionHelper's
convertAllMethodHandleArguments(...) method in SpEL.

Closes gh-33193
This commit is contained in:
Sam Brannen 2024-07-10 16:46:47 +02:00
parent 83ca2c0cff
commit fa2a58b9db
1 changed files with 6 additions and 7 deletions

View File

@ -380,12 +380,11 @@ public abstract class ReflectionHelper {
conversionOccurred |= (argument != arguments[i]); conversionOccurred |= (argument != arguments[i]);
} }
Class<?> varArgClass = methodHandleType.lastParameterType().componentType(); Class<?> varArgClass = methodHandleType.lastParameterType();
ResolvableType varArgResolvableType = ResolvableType.forClass(varArgClass); ResolvableType varArgResolvableType = ResolvableType.forClass(varArgClass);
TypeDescriptor targetType = new TypeDescriptor(varArgResolvableType, varArgClass, null); TypeDescriptor targetType = new TypeDescriptor(varArgResolvableType, varArgClass.componentType(), null);
TypeDescriptor componentTypeDesc = targetType.getElementTypeDescriptor(); TypeDescriptor componentTypeDesc = targetType.getElementTypeDescriptor();
// TODO Determine why componentTypeDesc can be null. Assert.state(componentTypeDesc != null, "Component type must not be null for a varargs array");
// Assert.state(componentTypeDesc != null, "Component type must not be null for a varargs array");
// If the target is varargs and there is just one more argument, then convert it here. // If the target is varargs and there is just one more argument, then convert it here.
if (varargsPosition == arguments.length - 1) { if (varargsPosition == arguments.length - 1) {
@ -393,7 +392,7 @@ public abstract class ReflectionHelper {
TypeDescriptor sourceType = TypeDescriptor.forObject(argument); TypeDescriptor sourceType = TypeDescriptor.forObject(argument);
if (argument == null) { if (argument == null) {
// Perform the equivalent of GenericConversionService.convertNullSource() for a single argument. // Perform the equivalent of GenericConversionService.convertNullSource() for a single argument.
if (componentTypeDesc != null && componentTypeDesc.getObjectType() == Optional.class) { if (componentTypeDesc.getObjectType() == Optional.class) {
arguments[varargsPosition] = Optional.empty(); arguments[varargsPosition] = Optional.empty();
conversionOccurred = true; conversionOccurred = true;
} }
@ -402,7 +401,7 @@ public abstract class ReflectionHelper {
// convert it or wrap it in an array. For example, using StringToArrayConverter to // convert it or wrap it in an array. For example, using StringToArrayConverter to
// convert a String containing a comma would result in the String being split and // convert a String containing a comma would result in the String being split and
// repackaged in an array when it should be used as-is. // repackaged in an array when it should be used as-is.
else if (componentTypeDesc != null && !sourceType.isAssignableTo(componentTypeDesc)) { else if (!sourceType.isAssignableTo(componentTypeDesc)) {
arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType); arguments[varargsPosition] = converter.convertValue(argument, sourceType, targetType);
} }
// Possible outcomes of the above if-else block: // Possible outcomes of the above if-else block:
@ -420,7 +419,7 @@ public abstract class ReflectionHelper {
else { else {
for (int i = varargsPosition; i < arguments.length; i++) { for (int i = varargsPosition; i < arguments.length; i++) {
Object argument = arguments[i]; Object argument = arguments[i];
arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), componentTypeDesc);
conversionOccurred |= (argument != arguments[i]); conversionOccurred |= (argument != arguments[i]);
} }
} }