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