|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2013 the original author or authors. |
| 2 | + * Copyright 2002-2022 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
47 | 47 | *
|
48 | 48 | * @author Andy Clement
|
49 | 49 | * @author Juergen Hoeller
|
| 50 | + * @author Sam Brannen |
50 | 51 | * @since 3.0
|
51 | 52 | */
|
52 | 53 | public class ConstructorReference extends SpelNodeImpl {
|
53 | 54 |
|
54 |
| - private boolean isArrayConstructor = false; |
| 55 | + /** |
| 56 | + * Maximum number of elements permitted in an array declaration, applying |
| 57 | + * to one-dimensional as well as multi-dimensional arrays. |
| 58 | + * @since 5.2.20 |
| 59 | + */ |
| 60 | + private static final int MAX_ARRAY_ELEMENTS = 256 * 1024; // 256K |
| 61 | + |
| 62 | + private final boolean isArrayConstructor; |
55 | 63 |
|
56 | 64 | private SpelNodeImpl[] dimensions;
|
57 | 65 |
|
@@ -250,14 +258,19 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException
|
250 | 258 | if (this.dimensions.length == 1) {
|
251 | 259 | TypedValue o = this.dimensions[0].getTypedValue(state);
|
252 | 260 | int arraySize = ExpressionUtils.toInt(typeConverter, o);
|
| 261 | + checkNumElements(arraySize); |
253 | 262 | newArray = Array.newInstance(componentType, arraySize);
|
254 | 263 | }
|
255 | 264 | else {
|
256 | 265 | // Multi-dimensional - hold onto your hat!
|
257 | 266 | int[] dims = new int[this.dimensions.length];
|
| 267 | + long numElements = 1; |
258 | 268 | for (int d = 0; d < this.dimensions.length; d++) {
|
259 | 269 | TypedValue o = this.dimensions[d].getTypedValue(state);
|
260 |
| - dims[d] = ExpressionUtils.toInt(typeConverter, o); |
| 270 | + int arraySize = ExpressionUtils.toInt(typeConverter, o); |
| 271 | + dims[d] = arraySize; |
| 272 | + numElements *= arraySize; |
| 273 | + checkNumElements(numElements); |
261 | 274 | }
|
262 | 275 | newArray = Array.newInstance(componentType, dims);
|
263 | 276 | }
|
@@ -317,6 +330,13 @@ else if (arrayTypeCode == TypeCode.BYTE) {
|
317 | 330 | return new TypedValue(newArray);
|
318 | 331 | }
|
319 | 332 |
|
| 333 | + private void checkNumElements(long numElements) { |
| 334 | + if (numElements >= MAX_ARRAY_ELEMENTS) { |
| 335 | + throw new SpelEvaluationException(getStartPosition(), |
| 336 | + SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, MAX_ARRAY_ELEMENTS); |
| 337 | + } |
| 338 | + } |
| 339 | + |
320 | 340 | private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter,
|
321 | 341 | InlineList initializer, Class<?> componentType) {
|
322 | 342 | TypeDescriptor toTypeDescriptor = TypeDescriptor.valueOf(componentType);
|
|
0 commit comments