@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2002 - 2021 the original author or authors .
* Copyright 2002 - 2022 the original author or authors .
*
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -53,10 +53,18 @@ import org.springframework.util.Assert;
*
*
* @author Andy Clement
* @author Andy Clement
* @author Juergen Hoeller
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3 . 0
* @since 3 . 0
* /
* /
public class ConstructorReference extends SpelNodeImpl {
public class ConstructorReference extends SpelNodeImpl {
/ * *
* Maximum number of elements permitted in an array declaration , applying
* to one - dimensional as well as multi - dimensional arrays .
* @since 5 . 2 . 20
* /
private static final int MAX_ARRAY_ELEMENTS = 256 * 1024 ; // 256K
private final boolean isArrayConstructor ;
private final boolean isArrayConstructor ;
@Nullable
@Nullable
@ -259,14 +267,19 @@ public class ConstructorReference extends SpelNodeImpl {
// Shortcut for 1-dimensional
// Shortcut for 1-dimensional
TypedValue o = this . dimensions [ 0 ] . getTypedValue ( state ) ;
TypedValue o = this . dimensions [ 0 ] . getTypedValue ( state ) ;
int arraySize = ExpressionUtils . toInt ( typeConverter , o ) ;
int arraySize = ExpressionUtils . toInt ( typeConverter , o ) ;
checkNumElements ( arraySize ) ;
newArray = Array . newInstance ( componentType , arraySize ) ;
newArray = Array . newInstance ( componentType , arraySize ) ;
}
}
else {
else {
// Multi-dimensional - hold onto your hat!
// Multi-dimensional - hold onto your hat!
int [ ] dims = new int [ this . dimensions . length ] ;
int [ ] dims = new int [ this . dimensions . length ] ;
long numElements = 1 ;
for ( int d = 0 ; d < this . dimensions . length ; d + + ) {
for ( int d = 0 ; d < this . dimensions . length ; d + + ) {
TypedValue o = this . dimensions [ d ] . getTypedValue ( state ) ;
TypedValue o = this . dimensions [ d ] . getTypedValue ( state ) ;
dims [ d ] = ExpressionUtils . toInt ( typeConverter , o ) ;
int arraySize = ExpressionUtils . toInt ( typeConverter , o ) ;
dims [ d ] = arraySize ;
numElements * = arraySize ;
checkNumElements ( numElements ) ;
}
}
newArray = Array . newInstance ( componentType , dims ) ;
newArray = Array . newInstance ( componentType , dims ) ;
}
}
@ -327,6 +340,13 @@ public class ConstructorReference extends SpelNodeImpl {
return new TypedValue ( newArray ) ;
return new TypedValue ( newArray ) ;
}
}
private void checkNumElements ( long numElements ) {
if ( numElements > = MAX_ARRAY_ELEMENTS ) {
throw new SpelEvaluationException ( getStartPosition ( ) ,
SpelMessage . MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED , MAX_ARRAY_ELEMENTS ) ;
}
}
private void populateReferenceTypeArray ( ExpressionState state , Object newArray , TypeConverter typeConverter ,
private void populateReferenceTypeArray ( ExpressionState state , Object newArray , TypeConverter typeConverter ,
InlineList initializer , Class < ? > componentType ) {
InlineList initializer , Class < ? > componentType ) {