|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2021 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.
|
|
53 | 53 | *
|
54 | 54 | * @author Andy Clement
|
55 | 55 | * @author Juergen Hoeller
|
| 56 | + * @author Sam Brannen |
56 | 57 | * @since 3.0
|
57 | 58 | */
|
58 | 59 | public class ConstructorReference extends SpelNodeImpl {
|
59 | 60 |
|
| 61 | + /** |
| 62 | + * Maximum number of elements permitted in an array declaration, applying |
| 63 | + * to one-dimensional as well as multi-dimensional arrays. |
| 64 | + * @since 5.2.20 |
| 65 | + */ |
| 66 | + private static final int MAX_ARRAY_ELEMENTS = 256 * 1024; // 256K |
| 67 | + |
60 | 68 | private final boolean isArrayConstructor;
|
61 | 69 |
|
62 | 70 | @Nullable
|
@@ -259,14 +267,19 @@ private TypedValue createArray(ExpressionState state) throws EvaluationException
|
259 | 267 | // Shortcut for 1-dimensional
|
260 | 268 | TypedValue o = this.dimensions[0].getTypedValue(state);
|
261 | 269 | int arraySize = ExpressionUtils.toInt(typeConverter, o);
|
| 270 | + checkNumElements(arraySize); |
262 | 271 | newArray = Array.newInstance(componentType, arraySize);
|
263 | 272 | }
|
264 | 273 | else {
|
265 | 274 | // Multi-dimensional - hold onto your hat!
|
266 | 275 | int[] dims = new int[this.dimensions.length];
|
| 276 | + long numElements = 1; |
267 | 277 | for (int d = 0; d < this.dimensions.length; d++) {
|
268 | 278 | TypedValue o = this.dimensions[d].getTypedValue(state);
|
269 |
| - dims[d] = ExpressionUtils.toInt(typeConverter, o); |
| 279 | + int arraySize = ExpressionUtils.toInt(typeConverter, o); |
| 280 | + dims[d] = arraySize; |
| 281 | + numElements *= arraySize; |
| 282 | + checkNumElements(numElements); |
270 | 283 | }
|
271 | 284 | newArray = Array.newInstance(componentType, dims);
|
272 | 285 | }
|
@@ -327,6 +340,13 @@ else if (arrayTypeCode == TypeCode.SHORT) {
|
327 | 340 | return new TypedValue(newArray);
|
328 | 341 | }
|
329 | 342 |
|
| 343 | + private void checkNumElements(long numElements) { |
| 344 | + if (numElements >= MAX_ARRAY_ELEMENTS) { |
| 345 | + throw new SpelEvaluationException(getStartPosition(), |
| 346 | + SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, MAX_ARRAY_ELEMENTS); |
| 347 | + } |
| 348 | + } |
| 349 | + |
330 | 350 | private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter,
|
331 | 351 | InlineList initializer, Class<?> componentType) {
|
332 | 352 |
|
|
0 commit comments